Merge "LayoutLib: Better support for compact/elegant fonts." into lmp-preview-dev
diff --git a/Android.mk b/Android.mk
index 7c01ed9..52459ae 100644
--- a/Android.mk
+++ b/Android.mk
@@ -77,9 +77,9 @@
 	core/java/android/app/ISearchManagerCallback.aidl \
 	core/java/android/app/IServiceConnection.aidl \
 	core/java/android/app/IStopUserCallback.aidl \
-	core/java/android/app/task/ITaskCallback.aidl \
-	core/java/android/app/task/ITaskManager.aidl \
-	core/java/android/app/task/ITaskService.aidl \
+	core/java/android/app/job/IJobCallback.aidl \
+	core/java/android/app/job/IJobScheduler.aidl \
+	core/java/android/app/job/IJobService.aidl \
 	core/java/android/app/IThumbnailRetriever.aidl \
 	core/java/android/app/ITransientNotification.aidl \
 	core/java/android/app/IUiAutomationConnection.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index f3bb9b6..5b027b3 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -197,3 +197,6 @@
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes/android/app/task)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/app/task)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/classes/android/app/TaskManager)
diff --git a/api/current.txt b/api/current.txt
index 7d8e796..8d33755 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -245,7 +245,7 @@
     field public static final int actionBarTabBarStyle = 16843508; // 0x10102f4
     field public static final int actionBarTabStyle = 16843507; // 0x10102f3
     field public static final int actionBarTabTextStyle = 16843509; // 0x10102f5
-    field public static final int actionBarTheme = 16843828; // 0x1010434
+    field public static final int actionBarTheme = 16843827; // 0x1010433
     field public static final int actionBarWidgetTheme = 16843671; // 0x1010397
     field public static final int actionButtonStyle = 16843480; // 0x10102d8
     field public static final int actionDropDownStyle = 16843479; // 0x10102d7
@@ -262,7 +262,7 @@
     field public static final int actionModeSplitBackground = 16843677; // 0x101039d
     field public static final int actionModeStyle = 16843668; // 0x1010394
     field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
-    field public static final int actionOverflowMenuStyle = 16843847; // 0x1010447
+    field public static final int actionOverflowMenuStyle = 16843846; // 0x1010446
     field public static final int actionProviderClass = 16843657; // 0x1010389
     field public static final int actionViewClass = 16843516; // 0x10102fc
     field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
@@ -308,7 +308,7 @@
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
     field public static final int autoLink = 16842928; // 0x10100b0
     field public static final int autoMirrored = 16843754; // 0x10103ea
-    field public static final int autoRemoveFromRecents = 16843850; // 0x101044a
+    field public static final int autoRemoveFromRecents = 16843849; // 0x1010449
     field public static final int autoStart = 16843445; // 0x10102b5
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
@@ -381,22 +381,22 @@
     field public static final int codes = 16843330; // 0x1010242
     field public static final int collapseColumns = 16843083; // 0x101014b
     field public static final int color = 16843173; // 0x10101a5
-    field public static final int colorAccent = 16843832; // 0x1010438
+    field public static final int colorAccent = 16843831; // 0x1010437
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
     field public static final int colorBackground = 16842801; // 0x1010031
     field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
-    field public static final int colorButtonNormal = 16843822; // 0x101042e
-    field public static final int colorControlActivated = 16843821; // 0x101042d
-    field public static final int colorControlHighlight = 16843823; // 0x101042f
-    field public static final int colorControlNormal = 16843820; // 0x101042c
+    field public static final int colorButtonNormal = 16843821; // 0x101042d
+    field public static final int colorControlActivated = 16843820; // 0x101042c
+    field public static final int colorControlHighlight = 16843822; // 0x101042e
+    field public static final int colorControlNormal = 16843819; // 0x101042b
     field public static final int colorFocusedHighlight = 16843663; // 0x101038f
     field public static final int colorForeground = 16842800; // 0x1010030
     field public static final int colorForegroundInverse = 16843270; // 0x1010206
     field public static final int colorLongPressedHighlight = 16843662; // 0x101038e
     field public static final int colorMultiSelectHighlight = 16843665; // 0x1010391
     field public static final int colorPressedHighlight = 16843661; // 0x101038d
-    field public static final int colorPrimary = 16843830; // 0x1010436
-    field public static final int colorPrimaryDark = 16843831; // 0x1010437
+    field public static final int colorPrimary = 16843829; // 0x1010435
+    field public static final int colorPrimaryDark = 16843830; // 0x1010436
     field public static final int columnCount = 16843639; // 0x1010377
     field public static final int columnDelay = 16843215; // 0x10101cf
     field public static final int columnOrderPreserved = 16843640; // 0x1010378
@@ -411,10 +411,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 contentInsetEnd = 16843863; // 0x1010457
-    field public static final int contentInsetLeft = 16843864; // 0x1010458
-    field public static final int contentInsetRight = 16843865; // 0x1010459
-    field public static final int contentInsetStart = 16843862; // 0x1010456
+    field public static final int contentInsetEnd = 16843862; // 0x1010456
+    field public static final int contentInsetLeft = 16843863; // 0x1010457
+    field public static final int contentInsetRight = 16843864; // 0x1010458
+    field public static final int contentInsetStart = 16843861; // 0x1010455
     field public static final int controlX1 = 16843798; // 0x1010416
     field public static final int controlX2 = 16843800; // 0x1010418
     field public static final int controlY1 = 16843799; // 0x1010417
@@ -459,7 +459,7 @@
     field public static final int dividerHorizontal = 16843564; // 0x101032c
     field public static final int dividerPadding = 16843562; // 0x101032a
     field public static final int dividerVertical = 16843530; // 0x101030a
-    field public static final int documentLaunchMode = 16843848; // 0x1010448
+    field public static final int documentLaunchMode = 16843847; // 0x1010447
     field public static final int drawSelectorOnTop = 16843004; // 0x10100fc
     field public static final int drawable = 16843161; // 0x1010199
     field public static final int drawableBottom = 16843118; // 0x101016e
@@ -488,8 +488,8 @@
     field public static final int editTextStyle = 16842862; // 0x101006e
     field public static final deprecated int editable = 16843115; // 0x101016b
     field public static final int editorExtras = 16843300; // 0x1010224
-    field public static final int elegantTextHeight = 16843868; // 0x101045c
-    field public static final int elevation = 16843843; // 0x1010443
+    field public static final int elegantTextHeight = 16843867; // 0x101045b
+    field public static final int elevation = 16843842; // 0x1010442
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
     field public static final int enabled = 16842766; // 0x101000e
@@ -499,10 +499,10 @@
     field public static final int entries = 16842930; // 0x10100b2
     field public static final int entryValues = 16843256; // 0x10101f8
     field public static final int eventsInterceptionEnabled = 16843389; // 0x101027d
-    field public static final int excludeClass = 16843845; // 0x1010445
+    field public static final int excludeClass = 16843844; // 0x1010444
     field public static final int excludeFromRecents = 16842775; // 0x1010017
-    field public static final int excludeId = 16843844; // 0x1010444
-    field public static final int excludeViewName = 16843857; // 0x1010451
+    field public static final int excludeId = 16843843; // 0x1010443
+    field public static final int excludeViewName = 16843856; // 0x1010450
     field public static final int exitFadeDuration = 16843533; // 0x101030d
     field public static final int expandableListPreferredChildIndicatorLeft = 16842834; // 0x1010052
     field public static final int expandableListPreferredChildIndicatorRight = 16842835; // 0x1010053
@@ -564,7 +564,7 @@
     field public static final int freezesText = 16843116; // 0x101016c
     field public static final int fromAlpha = 16843210; // 0x10101ca
     field public static final int fromDegrees = 16843187; // 0x10101b3
-    field public static final int fromId = 16843853; // 0x101044d
+    field public static final int fromId = 16843852; // 0x101044c
     field public static final int fromScene = 16843741; // 0x10103dd
     field public static final int fromXDelta = 16843206; // 0x10101c6
     field public static final int fromXScale = 16843202; // 0x10101c2
@@ -597,7 +597,7 @@
     field public static final int headerBackground = 16843055; // 0x101012f
     field public static final int headerDividersEnabled = 16843310; // 0x101022e
     field public static final int height = 16843093; // 0x1010155
-    field public static final int hideOnContentScroll = 16843846; // 0x1010446
+    field public static final int hideOnContentScroll = 16843845; // 0x1010445
     field public static final int hint = 16843088; // 0x1010150
     field public static final int homeAsUpIndicator = 16843531; // 0x101030b
     field public static final int homeLayout = 16843549; // 0x101031d
@@ -792,7 +792,7 @@
     field public static final int manageSpaceActivity = 16842756; // 0x1010004
     field public static final int mapViewStyle = 16842890; // 0x101008a
     field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
-    field public static final int matchOrder = 16843858; // 0x1010452
+    field public static final int matchOrder = 16843857; // 0x1010451
     field public static final int max = 16843062; // 0x1010136
     field public static final int maxDate = 16843584; // 0x1010340
     field public static final int maxEms = 16843095; // 0x1010157
@@ -801,7 +801,7 @@
     field public static final int maxLength = 16843104; // 0x1010160
     field public static final int maxLevel = 16843186; // 0x10101b2
     field public static final int maxLines = 16843091; // 0x1010153
-    field public static final int maxRecents = 16843849; // 0x1010449
+    field public static final int maxRecents = 16843848; // 0x1010448
     field public static final int maxRows = 16843059; // 0x1010133
     field public static final int maxSdkVersion = 16843377; // 0x1010271
     field public static final int maxWidth = 16843039; // 0x101011f
@@ -826,10 +826,10 @@
     field public static final int moreIcon = 16843061; // 0x1010135
     field public static final int multiprocess = 16842771; // 0x1010013
     field public static final int name = 16842755; // 0x1010003
-    field public static final int navigationBarColor = 16843861; // 0x1010455
+    field public static final int navigationBarColor = 16843860; // 0x1010454
     field public static final int navigationMode = 16843471; // 0x10102cf
     field public static final int negativeButtonText = 16843254; // 0x10101f6
-    field public static final int nestedScrollingEnabled = 16843833; // 0x1010439
+    field public static final int nestedScrollingEnabled = 16843832; // 0x1010438
     field public static final int nextFocusDown = 16842980; // 0x10100e4
     field public static final int nextFocusForward = 16843580; // 0x101033c
     field public static final int nextFocusLeft = 16842977; // 0x10100e1
@@ -860,7 +860,7 @@
     field public static final int paddingBottom = 16842969; // 0x10100d9
     field public static final int paddingEnd = 16843700; // 0x10103b4
     field public static final int paddingLeft = 16842966; // 0x10100d6
-    field public static final int paddingMode = 16843866; // 0x101045a
+    field public static final int paddingMode = 16843865; // 0x1010459
     field public static final int paddingRight = 16842968; // 0x10100d8
     field public static final int paddingStart = 16843699; // 0x10103b3
     field public static final int paddingTop = 16842967; // 0x10100d7
@@ -879,11 +879,10 @@
     field public static final int permissionFlags = 16843719; // 0x10103c7
     field public static final int permissionGroup = 16842762; // 0x101000a
     field public static final int permissionGroupFlags = 16843717; // 0x10103c5
-    field public static final int persistable = 16843824; // 0x1010430
+    field public static final int persistable = 16843823; // 0x101042f
     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 = 16843819; // 0x101042b
     field public static final int pivotX = 16843189; // 0x10101b5
     field public static final int pivotY = 16843190; // 0x10101b6
     field public static final int popupAnimationStyle = 16843465; // 0x10102c9
@@ -956,7 +955,7 @@
     field public static final int restoreAnyVersion = 16843450; // 0x10102ba
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
     field public static final int restrictedAccountType = 16843733; // 0x10103d5
-    field public static final int reversible = 16843854; // 0x101044e
+    field public static final int reversible = 16843853; // 0x101044d
     field public static final int right = 16843183; // 0x10101af
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
@@ -1010,10 +1009,10 @@
     field public static final int selectAllOnFocus = 16843102; // 0x101015e
     field public static final int selectable = 16843238; // 0x10101e6
     field public static final int selectableItemBackground = 16843534; // 0x101030e
-    field public static final int selectableItemBackgroundBorderless = 16843867; // 0x101045b
+    field public static final int selectableItemBackgroundBorderless = 16843866; // 0x101045a
     field public static final int selectedDateVerticalBar = 16843591; // 0x1010347
     field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
-    field public static final int sessionService = 16843840; // 0x1010440
+    field public static final int sessionService = 16843839; // 0x101043f
     field public static final int settingsActivity = 16843301; // 0x1010225
     field public static final int setupActivity = 16843766; // 0x10103f6
     field public static final int shadowColor = 16843105; // 0x1010161
@@ -1035,7 +1034,7 @@
     field public static final int shrinkColumns = 16843082; // 0x101014a
     field public static final deprecated int singleLine = 16843101; // 0x101015d
     field public static final int singleUser = 16843711; // 0x10103bf
-    field public static final int slideEdge = 16843827; // 0x1010433
+    field public static final int slideEdge = 16843826; // 0x1010432
     field public static final int smallIcon = 16843422; // 0x101029e
     field public static final int smallScreens = 16843396; // 0x1010284
     field public static final int smoothScrollbar = 16843313; // 0x1010231
@@ -1047,19 +1046,19 @@
     field public static final int spinnerStyle = 16842881; // 0x1010081
     field public static final int spinnersShown = 16843595; // 0x101034b
     field public static final int splitMotionEvents = 16843503; // 0x10102ef
-    field public static final int splitTrack = 16843855; // 0x101044f
+    field public static final int splitTrack = 16843854; // 0x101044e
     field public static final int src = 16843033; // 0x1010119
     field public static final int ssp = 16843747; // 0x10103e3
     field public static final int sspPattern = 16843749; // 0x10103e5
     field public static final int sspPrefix = 16843748; // 0x10103e4
     field public static final int stackFromBottom = 16843005; // 0x10100fd
-    field public static final int stackViewStyle = 16843841; // 0x1010441
+    field public static final int stackViewStyle = 16843840; // 0x1010440
     field public static final int starStyle = 16842882; // 0x1010082
     field public static final int startColor = 16843165; // 0x101019d
     field public static final int startDelay = 16843746; // 0x10103e2
     field public static final int startOffset = 16843198; // 0x10101be
     field public static final deprecated int startYear = 16843132; // 0x101017c
-    field public static final int stateListAnimator = 16843851; // 0x101044b
+    field public static final int stateListAnimator = 16843850; // 0x101044a
     field public static final int stateNotNeeded = 16842774; // 0x1010016
     field public static final int state_above_anchor = 16842922; // 0x10100aa
     field public static final int state_accelerated = 16843547; // 0x101031b
@@ -1084,7 +1083,7 @@
     field public static final int state_single = 16842915; // 0x10100a3
     field public static final int state_window_focused = 16842909; // 0x101009d
     field public static final int staticWallpaperPreview = 16843569; // 0x1010331
-    field public static final int statusBarColor = 16843860; // 0x1010454
+    field public static final int statusBarColor = 16843859; // 0x1010453
     field public static final int stepSize = 16843078; // 0x1010146
     field public static final int stopWithTask = 16843626; // 0x101036a
     field public static final int streamType = 16843273; // 0x1010209
@@ -1096,7 +1095,7 @@
     field public static final int strokeOpacity = 16843810; // 0x1010422
     field public static final int strokeWidth = 16843811; // 0x1010423
     field public static final int subtitle = 16843473; // 0x10102d1
-    field public static final int subtitleTextAppearance = 16843826; // 0x1010432
+    field public static final int subtitleTextAppearance = 16843825; // 0x1010431
     field public static final int subtitleTextStyle = 16843513; // 0x10102f9
     field public static final int subtypeExtraValue = 16843674; // 0x101039a
     field public static final int subtypeId = 16843713; // 0x10103c1
@@ -1113,7 +1112,7 @@
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
     field public static final int switchPreferenceStyle = 16843629; // 0x101036d
-    field public static final int switchStyle = 16843842; // 0x1010442
+    field public static final int switchStyle = 16843841; // 0x1010441
     field public static final int switchTextAppearance = 16843630; // 0x101036e
     field public static final int switchTextOff = 16843628; // 0x101036c
     field public static final int switchTextOn = 16843627; // 0x101036b
@@ -1129,7 +1128,7 @@
     field public static final int targetId = 16843740; // 0x10103dc
     field public static final int targetPackage = 16842785; // 0x1010021
     field public static final int targetSdkVersion = 16843376; // 0x1010270
-    field public static final int targetViewName = 16843856; // 0x1010450
+    field public static final int targetViewName = 16843855; // 0x101044f
     field public static final int taskAffinity = 16842770; // 0x1010012
     field public static final int taskCloseEnterAnimation = 16842942; // 0x10100be
     field public static final int taskCloseExitAnimation = 16842943; // 0x10100bf
@@ -1151,7 +1150,7 @@
     field public static final int textAppearanceLargeInverse = 16842819; // 0x1010043
     field public static final int textAppearanceLargePopupMenu = 16843521; // 0x1010301
     field public static final int textAppearanceListItem = 16843678; // 0x101039e
-    field public static final int textAppearanceListItemSecondary = 16843829; // 0x1010435
+    field public static final int textAppearanceListItemSecondary = 16843828; // 0x1010434
     field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
     field public static final int textAppearanceMedium = 16842817; // 0x1010041
     field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
@@ -1215,11 +1214,11 @@
     field public static final int tintMode = 16843797; // 0x1010415
     field public static final int title = 16843233; // 0x10101e1
     field public static final int titleCondensed = 16843234; // 0x10101e2
-    field public static final int titleTextAppearance = 16843825; // 0x1010431
+    field public static final int titleTextAppearance = 16843824; // 0x1010430
     field public static final int titleTextStyle = 16843512; // 0x10102f8
     field public static final int toAlpha = 16843211; // 0x10101cb
     field public static final int toDegrees = 16843188; // 0x10101b4
-    field public static final int toId = 16843852; // 0x101044c
+    field public static final int toId = 16843851; // 0x101044b
     field public static final int toScene = 16843742; // 0x10103de
     field public static final int toXDelta = 16843207; // 0x10101c7
     field public static final int toXScale = 16843203; // 0x10101c3
@@ -1300,8 +1299,8 @@
     field public static final int windowActionBar = 16843469; // 0x10102cd
     field public static final int windowActionBarOverlay = 16843492; // 0x10102e4
     field public static final int windowActionModeOverlay = 16843485; // 0x10102dd
-    field public static final int windowAllowEnterTransitionOverlap = 16843839; // 0x101043f
-    field public static final int windowAllowExitTransitionOverlap = 16843838; // 0x101043e
+    field public static final int windowAllowEnterTransitionOverlap = 16843838; // 0x101043e
+    field public static final int windowAllowExitTransitionOverlap = 16843837; // 0x101043d
     field public static final int windowAnimationStyle = 16842926; // 0x10100ae
     field public static final int windowBackground = 16842836; // 0x1010054
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
@@ -1309,12 +1308,12 @@
     field public static final int windowContentTransitionManager = 16843795; // 0x1010413
     field public static final int windowContentTransitions = 16843794; // 0x1010412
     field public static final int windowDisablePreview = 16843298; // 0x1010222
-    field public static final int windowDrawsSystemBarBackgrounds = 16843859; // 0x1010453
+    field public static final int windowDrawsSystemBarBackgrounds = 16843858; // 0x1010452
     field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
     field public static final int windowEnterAnimation = 16842932; // 0x10100b4
-    field public static final int windowEnterTransition = 16843834; // 0x101043a
+    field public static final int windowEnterTransition = 16843833; // 0x1010439
     field public static final int windowExitAnimation = 16842933; // 0x10100b5
-    field public static final int windowExitTransition = 16843835; // 0x101043b
+    field public static final int windowExitTransition = 16843834; // 0x101043a
     field public static final int windowFrame = 16842837; // 0x1010055
     field public static final int windowFullscreen = 16843277; // 0x101020d
     field public static final int windowHideAnimation = 16842935; // 0x10100b7
@@ -1325,8 +1324,8 @@
     field public static final int windowNoDisplay = 16843294; // 0x101021e
     field public static final int windowNoTitle = 16842838; // 0x1010056
     field public static final int windowOverscan = 16843727; // 0x10103cf
-    field public static final int windowSharedElementEnterTransition = 16843836; // 0x101043c
-    field public static final int windowSharedElementExitTransition = 16843837; // 0x101043d
+    field public static final int windowSharedElementEnterTransition = 16843835; // 0x101043b
+    field public static final int windowSharedElementExitTransition = 16843836; // 0x101043c
     field public static final int windowShowAnimation = 16842934; // 0x10100b6
     field public static final int windowShowWallpaper = 16843410; // 0x1010292
     field public static final int windowSoftInputMode = 16843307; // 0x101022b
@@ -1858,52 +1857,52 @@
     field public static final int TextAppearance_Inverse = 16973887; // 0x103003f
     field public static final int TextAppearance_Large = 16973890; // 0x1030042
     field public static final int TextAppearance_Large_Inverse = 16973891; // 0x1030043
-    field public static final int TextAppearance_Material = 16974348; // 0x103020c
-    field public static final int TextAppearance_Material_Body1 = 16974546; // 0x10302d2
-    field public static final int TextAppearance_Material_Body2 = 16974545; // 0x10302d1
-    field public static final int TextAppearance_Material_Button = 16974549; // 0x10302d5
-    field public static final int TextAppearance_Material_Caption = 16974547; // 0x10302d3
-    field public static final int TextAppearance_Material_DialogWindowTitle = 16974349; // 0x103020d
-    field public static final int TextAppearance_Material_Display1 = 16974541; // 0x10302cd
-    field public static final int TextAppearance_Material_Display2 = 16974540; // 0x10302cc
-    field public static final int TextAppearance_Material_Display3 = 16974539; // 0x10302cb
-    field public static final int TextAppearance_Material_Display4 = 16974538; // 0x10302ca
-    field public static final int TextAppearance_Material_Headline = 16974542; // 0x10302ce
-    field public static final int TextAppearance_Material_Inverse = 16974350; // 0x103020e
-    field public static final int TextAppearance_Material_Large = 16974351; // 0x103020f
-    field public static final int TextAppearance_Material_Large_Inverse = 16974352; // 0x1030210
-    field public static final int TextAppearance_Material_Medium = 16974353; // 0x1030211
-    field public static final int TextAppearance_Material_Medium_Inverse = 16974354; // 0x1030212
-    field public static final int TextAppearance_Material_Menu = 16974548; // 0x10302d4
-    field public static final int TextAppearance_Material_SearchResult_Subtitle = 16974355; // 0x1030213
-    field public static final int TextAppearance_Material_SearchResult_Title = 16974356; // 0x1030214
-    field public static final int TextAppearance_Material_Small = 16974357; // 0x1030215
-    field public static final int TextAppearance_Material_Small_Inverse = 16974358; // 0x1030216
-    field public static final int TextAppearance_Material_Subhead = 16974544; // 0x10302d0
-    field public static final int TextAppearance_Material_Title = 16974543; // 0x10302cf
-    field public static final int TextAppearance_Material_Widget = 16974360; // 0x1030218
-    field public static final int TextAppearance_Material_Widget_ActionBar_Menu = 16974361; // 0x1030219
-    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle = 16974362; // 0x103021a
-    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle_Inverse = 16974363; // 0x103021b
-    field public static final int TextAppearance_Material_Widget_ActionBar_Title = 16974364; // 0x103021c
-    field public static final int TextAppearance_Material_Widget_ActionBar_Title_Inverse = 16974365; // 0x103021d
-    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle = 16974366; // 0x103021e
-    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle_Inverse = 16974367; // 0x103021f
-    field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974368; // 0x1030220
-    field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974369; // 0x1030221
-    field public static final int TextAppearance_Material_Widget_Button = 16974370; // 0x1030222
-    field public static final int TextAppearance_Material_Widget_DropDownHint = 16974371; // 0x1030223
-    field public static final int TextAppearance_Material_Widget_DropDownItem = 16974372; // 0x1030224
-    field public static final int TextAppearance_Material_Widget_EditText = 16974373; // 0x1030225
-    field public static final int TextAppearance_Material_Widget_IconMenu_Item = 16974374; // 0x1030226
-    field public static final int TextAppearance_Material_Widget_PopupMenu = 16974375; // 0x1030227
-    field public static final int TextAppearance_Material_Widget_PopupMenu_Large = 16974376; // 0x1030228
-    field public static final int TextAppearance_Material_Widget_PopupMenu_Small = 16974377; // 0x1030229
-    field public static final int TextAppearance_Material_Widget_TabWidget = 16974378; // 0x103022a
-    field public static final int TextAppearance_Material_Widget_TextView = 16974379; // 0x103022b
-    field public static final int TextAppearance_Material_Widget_TextView_PopupMenu = 16974380; // 0x103022c
-    field public static final int TextAppearance_Material_Widget_TextView_SpinnerItem = 16974381; // 0x103022d
-    field public static final int TextAppearance_Material_WindowTitle = 16974359; // 0x1030217
+    field public static final int TextAppearance_Material = 16974350; // 0x103020e
+    field public static final int TextAppearance_Material_Body1 = 16974552; // 0x10302d8
+    field public static final int TextAppearance_Material_Body2 = 16974551; // 0x10302d7
+    field public static final int TextAppearance_Material_Button = 16974555; // 0x10302db
+    field public static final int TextAppearance_Material_Caption = 16974553; // 0x10302d9
+    field public static final int TextAppearance_Material_DialogWindowTitle = 16974351; // 0x103020f
+    field public static final int TextAppearance_Material_Display1 = 16974547; // 0x10302d3
+    field public static final int TextAppearance_Material_Display2 = 16974546; // 0x10302d2
+    field public static final int TextAppearance_Material_Display3 = 16974545; // 0x10302d1
+    field public static final int TextAppearance_Material_Display4 = 16974544; // 0x10302d0
+    field public static final int TextAppearance_Material_Headline = 16974548; // 0x10302d4
+    field public static final int TextAppearance_Material_Inverse = 16974352; // 0x1030210
+    field public static final int TextAppearance_Material_Large = 16974353; // 0x1030211
+    field public static final int TextAppearance_Material_Large_Inverse = 16974354; // 0x1030212
+    field public static final int TextAppearance_Material_Medium = 16974355; // 0x1030213
+    field public static final int TextAppearance_Material_Medium_Inverse = 16974356; // 0x1030214
+    field public static final int TextAppearance_Material_Menu = 16974554; // 0x10302da
+    field public static final int TextAppearance_Material_SearchResult_Subtitle = 16974357; // 0x1030215
+    field public static final int TextAppearance_Material_SearchResult_Title = 16974358; // 0x1030216
+    field public static final int TextAppearance_Material_Small = 16974359; // 0x1030217
+    field public static final int TextAppearance_Material_Small_Inverse = 16974360; // 0x1030218
+    field public static final int TextAppearance_Material_Subhead = 16974550; // 0x10302d6
+    field public static final int TextAppearance_Material_Title = 16974549; // 0x10302d5
+    field public static final int TextAppearance_Material_Widget = 16974362; // 0x103021a
+    field public static final int TextAppearance_Material_Widget_ActionBar_Menu = 16974363; // 0x103021b
+    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle = 16974364; // 0x103021c
+    field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle_Inverse = 16974365; // 0x103021d
+    field public static final int TextAppearance_Material_Widget_ActionBar_Title = 16974366; // 0x103021e
+    field public static final int TextAppearance_Material_Widget_ActionBar_Title_Inverse = 16974367; // 0x103021f
+    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle = 16974368; // 0x1030220
+    field public static final int TextAppearance_Material_Widget_ActionMode_Subtitle_Inverse = 16974369; // 0x1030221
+    field public static final int TextAppearance_Material_Widget_ActionMode_Title = 16974370; // 0x1030222
+    field public static final int TextAppearance_Material_Widget_ActionMode_Title_Inverse = 16974371; // 0x1030223
+    field public static final int TextAppearance_Material_Widget_Button = 16974372; // 0x1030224
+    field public static final int TextAppearance_Material_Widget_DropDownHint = 16974373; // 0x1030225
+    field public static final int TextAppearance_Material_Widget_DropDownItem = 16974374; // 0x1030226
+    field public static final int TextAppearance_Material_Widget_EditText = 16974375; // 0x1030227
+    field public static final int TextAppearance_Material_Widget_IconMenu_Item = 16974376; // 0x1030228
+    field public static final int TextAppearance_Material_Widget_PopupMenu = 16974377; // 0x1030229
+    field public static final int TextAppearance_Material_Widget_PopupMenu_Large = 16974378; // 0x103022a
+    field public static final int TextAppearance_Material_Widget_PopupMenu_Small = 16974379; // 0x103022b
+    field public static final int TextAppearance_Material_Widget_TabWidget = 16974380; // 0x103022c
+    field public static final int TextAppearance_Material_Widget_TextView = 16974381; // 0x103022d
+    field public static final int TextAppearance_Material_Widget_TextView_PopupMenu = 16974382; // 0x103022e
+    field public static final int TextAppearance_Material_Widget_TextView_SpinnerItem = 16974383; // 0x103022f
+    field public static final int TextAppearance_Material_WindowTitle = 16974361; // 0x1030219
     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_Small = 16973894; // 0x1030046
@@ -1929,12 +1928,12 @@
     field public static final int TextAppearance_Widget_TextView_SpinnerItem = 16973906; // 0x1030052
     field public static final int TextAppearance_WindowTitle = 16973907; // 0x1030053
     field public static final int Theme = 16973829; // 0x1030005
-    field public static final int ThemeOverlay = 16974412; // 0x103024c
-    field public static final int ThemeOverlay_Material = 16974413; // 0x103024d
-    field public static final int ThemeOverlay_Material_ActionBar = 16974414; // 0x103024e
-    field public static final int ThemeOverlay_Material_Dark = 16974416; // 0x1030250
-    field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974417; // 0x1030251
-    field public static final int ThemeOverlay_Material_Light = 16974415; // 0x103024f
+    field public static final int ThemeOverlay = 16974416; // 0x1030250
+    field public static final int ThemeOverlay_Material = 16974417; // 0x1030251
+    field public static final int ThemeOverlay_Material_ActionBar = 16974418; // 0x1030252
+    field public static final int ThemeOverlay_Material_Dark = 16974420; // 0x1030254
+    field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974421; // 0x1030255
+    field public static final int ThemeOverlay_Material_Light = 16974419; // 0x1030253
     field public static final int Theme_Black = 16973832; // 0x1030008
     field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
     field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
@@ -1964,6 +1963,7 @@
     field public static final int Theme_DeviceDefault_NoActionBar_Overscan = 16974303; // 0x10301df
     field public static final int Theme_DeviceDefault_NoActionBar_TranslucentDecor = 16974307; // 0x10301e3
     field public static final int Theme_DeviceDefault_Panel = 16974138; // 0x103013a
+    field public static final int Theme_DeviceDefault_Settings = 16974384; // 0x1030230
     field public static final int Theme_DeviceDefault_Wallpaper = 16974140; // 0x103013c
     field public static final int Theme_DeviceDefault_Wallpaper_NoTitleBar = 16974141; // 0x103013d
     field public static final int Theme_Dialog = 16973835; // 0x103000b
@@ -2001,36 +2001,37 @@
     field public static final int Theme_Light_NoTitleBar_Fullscreen = 16973838; // 0x103000e
     field public static final int Theme_Light_Panel = 16973914; // 0x103005a
     field public static final int Theme_Light_WallpaperSettings = 16973922; // 0x1030062
-    field public static final int Theme_Material = 16974382; // 0x103022e
-    field public static final int Theme_Material_Dialog = 16974383; // 0x103022f
-    field public static final int Theme_Material_DialogWhenLarge = 16974387; // 0x1030233
-    field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974388; // 0x1030234
-    field public static final int Theme_Material_Dialog_MinWidth = 16974384; // 0x1030230
-    field public static final int Theme_Material_Dialog_NoActionBar = 16974385; // 0x1030231
-    field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974386; // 0x1030232
-    field public static final int Theme_Material_InputMethod = 16974389; // 0x1030235
-    field public static final int Theme_Material_Light = 16974398; // 0x103023e
-    field public static final int Theme_Material_Light_DarkActionBar = 16974399; // 0x103023f
-    field public static final int Theme_Material_Light_Dialog = 16974400; // 0x1030240
-    field public static final int Theme_Material_Light_DialogWhenLarge = 16974404; // 0x1030244
-    field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974405; // 0x1030245
-    field public static final int Theme_Material_Light_Dialog_MinWidth = 16974401; // 0x1030241
-    field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974402; // 0x1030242
-    field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974403; // 0x1030243
-    field public static final int Theme_Material_Light_NoActionBar = 16974406; // 0x1030246
-    field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974407; // 0x1030247
-    field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974408; // 0x1030248
-    field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974409; // 0x1030249
-    field public static final int Theme_Material_Light_Panel = 16974410; // 0x103024a
-    field public static final int Theme_Material_Light_Voice = 16974411; // 0x103024b
-    field public static final int Theme_Material_NoActionBar = 16974390; // 0x1030236
-    field public static final int Theme_Material_NoActionBar_Fullscreen = 16974391; // 0x1030237
-    field public static final int Theme_Material_NoActionBar_Overscan = 16974392; // 0x1030238
-    field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974393; // 0x1030239
-    field public static final int Theme_Material_Panel = 16974394; // 0x103023a
-    field public static final int Theme_Material_Voice = 16974395; // 0x103023b
-    field public static final int Theme_Material_Wallpaper = 16974396; // 0x103023c
-    field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974397; // 0x103023d
+    field public static final int Theme_Material = 16974385; // 0x1030231
+    field public static final int Theme_Material_Dialog = 16974386; // 0x1030232
+    field public static final int Theme_Material_DialogWhenLarge = 16974390; // 0x1030236
+    field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974391; // 0x1030237
+    field public static final int Theme_Material_Dialog_MinWidth = 16974387; // 0x1030233
+    field public static final int Theme_Material_Dialog_NoActionBar = 16974388; // 0x1030234
+    field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974389; // 0x1030235
+    field public static final int Theme_Material_InputMethod = 16974392; // 0x1030238
+    field public static final int Theme_Material_Light = 16974402; // 0x1030242
+    field public static final int Theme_Material_Light_DarkActionBar = 16974403; // 0x1030243
+    field public static final int Theme_Material_Light_Dialog = 16974404; // 0x1030244
+    field public static final int Theme_Material_Light_DialogWhenLarge = 16974408; // 0x1030248
+    field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974409; // 0x1030249
+    field public static final int Theme_Material_Light_Dialog_MinWidth = 16974405; // 0x1030245
+    field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974406; // 0x1030246
+    field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974407; // 0x1030247
+    field public static final int Theme_Material_Light_NoActionBar = 16974410; // 0x103024a
+    field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974411; // 0x103024b
+    field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974412; // 0x103024c
+    field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974413; // 0x103024d
+    field public static final int Theme_Material_Light_Panel = 16974414; // 0x103024e
+    field public static final int Theme_Material_Light_Voice = 16974415; // 0x103024f
+    field public static final int Theme_Material_NoActionBar = 16974393; // 0x1030239
+    field public static final int Theme_Material_NoActionBar_Fullscreen = 16974394; // 0x103023a
+    field public static final int Theme_Material_NoActionBar_Overscan = 16974395; // 0x103023b
+    field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974396; // 0x103023c
+    field public static final int Theme_Material_Panel = 16974397; // 0x103023d
+    field public static final int Theme_Material_Settings = 16974398; // 0x103023e
+    field public static final int Theme_Material_Voice = 16974399; // 0x103023f
+    field public static final int Theme_Material_Wallpaper = 16974400; // 0x1030240
+    field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974401; // 0x1030241
     field public static final int Theme_NoDisplay = 16973909; // 0x1030055
     field public static final int Theme_NoTitleBar = 16973830; // 0x1030006
     field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
@@ -2092,7 +2093,7 @@
     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 = 16974344; // 0x1030208
+    field public static final int Widget_DeviceDefault_FastScroll = 16974346; // 0x103020a
     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
@@ -2126,7 +2127,7 @@
     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 = 16974346; // 0x103020a
+    field public static final int Widget_DeviceDefault_Light_FastScroll = 16974348; // 0x103020c
     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
@@ -2150,7 +2151,7 @@
     field public static final int Widget_DeviceDefault_Light_ScrollView = 16974225; // 0x1030191
     field public static final int Widget_DeviceDefault_Light_SeekBar = 16974220; // 0x103018c
     field public static final int Widget_DeviceDefault_Light_Spinner = 16974227; // 0x1030193
-    field public static final int Widget_DeviceDefault_Light_StackView = 16974347; // 0x103020b
+    field public static final int Widget_DeviceDefault_Light_StackView = 16974349; // 0x103020d
     field public static final int Widget_DeviceDefault_Light_Tab = 16974237; // 0x103019d
     field public static final int Widget_DeviceDefault_Light_TabWidget = 16974229; // 0x1030195
     field public static final int Widget_DeviceDefault_Light_TextView = 16974202; // 0x103017a
@@ -2174,7 +2175,7 @@
     field public static final int Widget_DeviceDefault_ScrollView = 16974170; // 0x103015a
     field public static final int Widget_DeviceDefault_SeekBar = 16974165; // 0x1030155
     field public static final int Widget_DeviceDefault_Spinner = 16974172; // 0x103015c
-    field public static final int Widget_DeviceDefault_StackView = 16974345; // 0x1030209
+    field public static final int Widget_DeviceDefault_StackView = 16974347; // 0x103020b
     field public static final int Widget_DeviceDefault_Tab = 16974189; // 0x103016d
     field public static final int Widget_DeviceDefault_TabWidget = 16974174; // 0x103015e
     field public static final int Widget_DeviceDefault_TextView = 16974150; // 0x1030146
@@ -2217,7 +2218,7 @@
     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 = 16974339; // 0x1030203
+    field public static final int Widget_Holo_FastScroll = 16974341; // 0x1030205
     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
@@ -2238,7 +2239,7 @@
     field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974119; // 0x1030127
     field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb
     field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6
-    field public static final int Widget_Holo_Light_Button_Borderless = 16974341; // 0x1030205
+    field public static final int Widget_Holo_Light_Button_Borderless = 16974343; // 0x1030207
     field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974107; // 0x103011b
     field public static final int Widget_Holo_Light_Button_Inset = 16974008; // 0x10300b8
     field public static final int Widget_Holo_Light_Button_Small = 16974007; // 0x10300b7
@@ -2252,7 +2253,7 @@
     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 = 16974342; // 0x1030206
+    field public static final int Widget_Holo_Light_FastScroll = 16974344; // 0x1030208
     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
@@ -2276,7 +2277,7 @@
     field public static final int Widget_Holo_Light_ScrollView = 16974033; // 0x10300d1
     field public static final int Widget_Holo_Light_SeekBar = 16974028; // 0x10300cc
     field public static final int Widget_Holo_Light_Spinner = 16974035; // 0x10300d3
-    field public static final int Widget_Holo_Light_StackView = 16974343; // 0x1030207
+    field public static final int Widget_Holo_Light_StackView = 16974345; // 0x1030209
     field public static final int Widget_Holo_Light_Tab = 16974052; // 0x10300e4
     field public static final int Widget_Holo_Light_TabWidget = 16974037; // 0x10300d5
     field public static final int Widget_Holo_Light_TextView = 16974010; // 0x10300ba
@@ -2300,7 +2301,7 @@
     field public static final int Widget_Holo_ScrollView = 16973987; // 0x10300a3
     field public static final int Widget_Holo_SeekBar = 16973982; // 0x103009e
     field public static final int Widget_Holo_Spinner = 16973989; // 0x10300a5
-    field public static final int Widget_Holo_StackView = 16974340; // 0x1030204
+    field public static final int Widget_Holo_StackView = 16974342; // 0x1030206
     field public static final int Widget_Holo_Tab = 16974051; // 0x10300e3
     field public static final int Widget_Holo_TabWidget = 16973991; // 0x10300a7
     field public static final int Widget_Holo_TextView = 16973967; // 0x103008f
@@ -2315,126 +2316,128 @@
     field public static final int Widget_ListView_DropDown = 16973872; // 0x1030030
     field public static final int Widget_ListView_Menu = 16973873; // 0x1030031
     field public static final int Widget_ListView_White = 16973871; // 0x103002f
-    field public static final int Widget_Material = 16974418; // 0x1030252
-    field public static final int Widget_Material_ActionBar = 16974419; // 0x1030253
-    field public static final int Widget_Material_ActionBar_Solid = 16974420; // 0x1030254
-    field public static final int Widget_Material_ActionBar_TabBar = 16974421; // 0x1030255
-    field public static final int Widget_Material_ActionBar_TabText = 16974422; // 0x1030256
-    field public static final int Widget_Material_ActionBar_TabView = 16974423; // 0x1030257
-    field public static final int Widget_Material_ActionButton = 16974424; // 0x1030258
-    field public static final int Widget_Material_ActionButton_CloseMode = 16974425; // 0x1030259
-    field public static final int Widget_Material_ActionButton_Overflow = 16974426; // 0x103025a
-    field public static final int Widget_Material_ActionMode = 16974427; // 0x103025b
-    field public static final int Widget_Material_AutoCompleteTextView = 16974428; // 0x103025c
-    field public static final int Widget_Material_Button = 16974429; // 0x103025d
-    field public static final int Widget_Material_ButtonBar = 16974435; // 0x1030263
-    field public static final int Widget_Material_ButtonBar_AlertDialog = 16974436; // 0x1030264
-    field public static final int Widget_Material_Button_Borderless = 16974430; // 0x103025e
-    field public static final int Widget_Material_Button_Borderless_Small = 16974431; // 0x103025f
-    field public static final int Widget_Material_Button_Inset = 16974432; // 0x1030260
-    field public static final int Widget_Material_Button_Small = 16974433; // 0x1030261
-    field public static final int Widget_Material_Button_Toggle = 16974434; // 0x1030262
-    field public static final int Widget_Material_CalendarView = 16974437; // 0x1030265
-    field public static final int Widget_Material_CheckedTextView = 16974438; // 0x1030266
-    field public static final int Widget_Material_CompoundButton_CheckBox = 16974439; // 0x1030267
-    field public static final int Widget_Material_CompoundButton_RadioButton = 16974440; // 0x1030268
-    field public static final int Widget_Material_CompoundButton_Star = 16974441; // 0x1030269
-    field public static final int Widget_Material_DatePicker = 16974442; // 0x103026a
-    field public static final int Widget_Material_DropDownItem = 16974443; // 0x103026b
-    field public static final int Widget_Material_DropDownItem_Spinner = 16974444; // 0x103026c
-    field public static final int Widget_Material_EditText = 16974445; // 0x103026d
-    field public static final int Widget_Material_ExpandableListView = 16974446; // 0x103026e
-    field public static final int Widget_Material_FastScroll = 16974447; // 0x103026f
-    field public static final int Widget_Material_GridView = 16974448; // 0x1030270
-    field public static final int Widget_Material_HorizontalScrollView = 16974449; // 0x1030271
-    field public static final int Widget_Material_ImageButton = 16974450; // 0x1030272
-    field public static final int Widget_Material_Light = 16974477; // 0x103028d
-    field public static final int Widget_Material_Light_ActionBar = 16974478; // 0x103028e
-    field public static final int Widget_Material_Light_ActionBar_Solid = 16974479; // 0x103028f
-    field public static final int Widget_Material_Light_ActionBar_TabBar = 16974480; // 0x1030290
-    field public static final int Widget_Material_Light_ActionBar_TabText = 16974481; // 0x1030291
-    field public static final int Widget_Material_Light_ActionBar_TabView = 16974482; // 0x1030292
-    field public static final int Widget_Material_Light_ActionButton = 16974483; // 0x1030293
-    field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974484; // 0x1030294
-    field public static final int Widget_Material_Light_ActionButton_Overflow = 16974485; // 0x1030295
-    field public static final int Widget_Material_Light_ActionMode = 16974486; // 0x1030296
-    field public static final int Widget_Material_Light_AutoCompleteTextView = 16974487; // 0x1030297
-    field public static final int Widget_Material_Light_Button = 16974488; // 0x1030298
-    field public static final int Widget_Material_Light_ButtonBar = 16974494; // 0x103029e
-    field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974495; // 0x103029f
-    field public static final int Widget_Material_Light_Button_Borderless = 16974489; // 0x1030299
-    field public static final int Widget_Material_Light_Button_Borderless_Small = 16974490; // 0x103029a
-    field public static final int Widget_Material_Light_Button_Inset = 16974491; // 0x103029b
-    field public static final int Widget_Material_Light_Button_Small = 16974492; // 0x103029c
-    field public static final int Widget_Material_Light_Button_Toggle = 16974493; // 0x103029d
-    field public static final int Widget_Material_Light_CalendarView = 16974496; // 0x10302a0
-    field public static final int Widget_Material_Light_CheckedTextView = 16974497; // 0x10302a1
-    field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974498; // 0x10302a2
-    field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974499; // 0x10302a3
-    field public static final int Widget_Material_Light_CompoundButton_Star = 16974500; // 0x10302a4
-    field public static final int Widget_Material_Light_DropDownItem = 16974501; // 0x10302a5
-    field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974502; // 0x10302a6
-    field public static final int Widget_Material_Light_EditText = 16974503; // 0x10302a7
-    field public static final int Widget_Material_Light_ExpandableListView = 16974504; // 0x10302a8
-    field public static final int Widget_Material_Light_FastScroll = 16974505; // 0x10302a9
-    field public static final int Widget_Material_Light_GridView = 16974506; // 0x10302aa
-    field public static final int Widget_Material_Light_HorizontalScrollView = 16974507; // 0x10302ab
-    field public static final int Widget_Material_Light_ImageButton = 16974508; // 0x10302ac
-    field public static final int Widget_Material_Light_ListPopupWindow = 16974509; // 0x10302ad
-    field public static final int Widget_Material_Light_ListView = 16974510; // 0x10302ae
-    field public static final int Widget_Material_Light_ListView_DropDown = 16974511; // 0x10302af
-    field public static final int Widget_Material_Light_MediaRouteButton = 16974512; // 0x10302b0
-    field public static final int Widget_Material_Light_PopupMenu = 16974513; // 0x10302b1
-    field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974514; // 0x10302b2
-    field public static final int Widget_Material_Light_PopupWindow = 16974515; // 0x10302b3
-    field public static final int Widget_Material_Light_ProgressBar = 16974516; // 0x10302b4
-    field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974517; // 0x10302b5
-    field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974518; // 0x10302b6
-    field public static final int Widget_Material_Light_ProgressBar_Large = 16974519; // 0x10302b7
-    field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974520; // 0x10302b8
-    field public static final int Widget_Material_Light_ProgressBar_Small = 16974521; // 0x10302b9
-    field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974522; // 0x10302ba
-    field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974523; // 0x10302bb
-    field public static final int Widget_Material_Light_RatingBar = 16974524; // 0x10302bc
-    field public static final int Widget_Material_Light_RatingBar_Indicator = 16974525; // 0x10302bd
-    field public static final int Widget_Material_Light_RatingBar_Small = 16974526; // 0x10302be
-    field public static final int Widget_Material_Light_ScrollView = 16974527; // 0x10302bf
-    field public static final int Widget_Material_Light_SeekBar = 16974528; // 0x10302c0
-    field public static final int Widget_Material_Light_SegmentedButton = 16974529; // 0x10302c1
-    field public static final int Widget_Material_Light_Spinner = 16974531; // 0x10302c3
-    field public static final int Widget_Material_Light_StackView = 16974530; // 0x10302c2
-    field public static final int Widget_Material_Light_Tab = 16974532; // 0x10302c4
-    field public static final int Widget_Material_Light_TabWidget = 16974533; // 0x10302c5
-    field public static final int Widget_Material_Light_TextView = 16974534; // 0x10302c6
-    field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974535; // 0x10302c7
-    field public static final int Widget_Material_Light_WebTextView = 16974536; // 0x10302c8
-    field public static final int Widget_Material_Light_WebView = 16974537; // 0x10302c9
-    field public static final int Widget_Material_ListPopupWindow = 16974451; // 0x1030273
-    field public static final int Widget_Material_ListView = 16974452; // 0x1030274
-    field public static final int Widget_Material_ListView_DropDown = 16974453; // 0x1030275
-    field public static final int Widget_Material_MediaRouteButton = 16974454; // 0x1030276
-    field public static final int Widget_Material_PopupMenu = 16974455; // 0x1030277
-    field public static final int Widget_Material_PopupMenu_Overflow = 16974456; // 0x1030278
-    field public static final int Widget_Material_PopupWindow = 16974457; // 0x1030279
-    field public static final int Widget_Material_ProgressBar = 16974458; // 0x103027a
-    field public static final int Widget_Material_ProgressBar_Horizontal = 16974459; // 0x103027b
-    field public static final int Widget_Material_ProgressBar_Large = 16974460; // 0x103027c
-    field public static final int Widget_Material_ProgressBar_Small = 16974461; // 0x103027d
-    field public static final int Widget_Material_ProgressBar_Small_Title = 16974462; // 0x103027e
-    field public static final int Widget_Material_RatingBar = 16974463; // 0x103027f
-    field public static final int Widget_Material_RatingBar_Indicator = 16974464; // 0x1030280
-    field public static final int Widget_Material_RatingBar_Small = 16974465; // 0x1030281
-    field public static final int Widget_Material_ScrollView = 16974466; // 0x1030282
-    field public static final int Widget_Material_SeekBar = 16974467; // 0x1030283
-    field public static final int Widget_Material_SegmentedButton = 16974468; // 0x1030284
-    field public static final int Widget_Material_Spinner = 16974470; // 0x1030286
-    field public static final int Widget_Material_StackView = 16974469; // 0x1030285
-    field public static final int Widget_Material_Tab = 16974471; // 0x1030287
-    field public static final int Widget_Material_TabWidget = 16974472; // 0x1030288
-    field public static final int Widget_Material_TextView = 16974473; // 0x1030289
-    field public static final int Widget_Material_TextView_SpinnerItem = 16974474; // 0x103028a
-    field public static final int Widget_Material_WebTextView = 16974475; // 0x103028b
-    field public static final int Widget_Material_WebView = 16974476; // 0x103028c
+    field public static final int Widget_Material = 16974422; // 0x1030256
+    field public static final int Widget_Material_ActionBar = 16974423; // 0x1030257
+    field public static final int Widget_Material_ActionBar_Solid = 16974424; // 0x1030258
+    field public static final int Widget_Material_ActionBar_TabBar = 16974425; // 0x1030259
+    field public static final int Widget_Material_ActionBar_TabText = 16974426; // 0x103025a
+    field public static final int Widget_Material_ActionBar_TabView = 16974427; // 0x103025b
+    field public static final int Widget_Material_ActionButton = 16974428; // 0x103025c
+    field public static final int Widget_Material_ActionButton_CloseMode = 16974429; // 0x103025d
+    field public static final int Widget_Material_ActionButton_Overflow = 16974430; // 0x103025e
+    field public static final int Widget_Material_ActionMode = 16974431; // 0x103025f
+    field public static final int Widget_Material_AutoCompleteTextView = 16974432; // 0x1030260
+    field public static final int Widget_Material_Button = 16974433; // 0x1030261
+    field public static final int Widget_Material_ButtonBar = 16974439; // 0x1030267
+    field public static final int Widget_Material_ButtonBar_AlertDialog = 16974440; // 0x1030268
+    field public static final int Widget_Material_Button_Borderless = 16974434; // 0x1030262
+    field public static final int Widget_Material_Button_Borderless_Small = 16974435; // 0x1030263
+    field public static final int Widget_Material_Button_Inset = 16974436; // 0x1030264
+    field public static final int Widget_Material_Button_Small = 16974437; // 0x1030265
+    field public static final int Widget_Material_Button_Toggle = 16974438; // 0x1030266
+    field public static final int Widget_Material_CalendarView = 16974441; // 0x1030269
+    field public static final int Widget_Material_CheckedTextView = 16974442; // 0x103026a
+    field public static final int Widget_Material_CompoundButton_CheckBox = 16974443; // 0x103026b
+    field public static final int Widget_Material_CompoundButton_RadioButton = 16974444; // 0x103026c
+    field public static final int Widget_Material_CompoundButton_Star = 16974445; // 0x103026d
+    field public static final int Widget_Material_DatePicker = 16974446; // 0x103026e
+    field public static final int Widget_Material_DropDownItem = 16974447; // 0x103026f
+    field public static final int Widget_Material_DropDownItem_Spinner = 16974448; // 0x1030270
+    field public static final int Widget_Material_EditText = 16974449; // 0x1030271
+    field public static final int Widget_Material_ExpandableListView = 16974450; // 0x1030272
+    field public static final int Widget_Material_FastScroll = 16974451; // 0x1030273
+    field public static final int Widget_Material_GridView = 16974452; // 0x1030274
+    field public static final int Widget_Material_HorizontalScrollView = 16974453; // 0x1030275
+    field public static final int Widget_Material_ImageButton = 16974454; // 0x1030276
+    field public static final int Widget_Material_Light = 16974483; // 0x1030293
+    field public static final int Widget_Material_Light_ActionBar = 16974484; // 0x1030294
+    field public static final int Widget_Material_Light_ActionBar_Solid = 16974485; // 0x1030295
+    field public static final int Widget_Material_Light_ActionBar_TabBar = 16974486; // 0x1030296
+    field public static final int Widget_Material_Light_ActionBar_TabText = 16974487; // 0x1030297
+    field public static final int Widget_Material_Light_ActionBar_TabView = 16974488; // 0x1030298
+    field public static final int Widget_Material_Light_ActionButton = 16974489; // 0x1030299
+    field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974490; // 0x103029a
+    field public static final int Widget_Material_Light_ActionButton_Overflow = 16974491; // 0x103029b
+    field public static final int Widget_Material_Light_ActionMode = 16974492; // 0x103029c
+    field public static final int Widget_Material_Light_AutoCompleteTextView = 16974493; // 0x103029d
+    field public static final int Widget_Material_Light_Button = 16974494; // 0x103029e
+    field public static final int Widget_Material_Light_ButtonBar = 16974500; // 0x10302a4
+    field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974501; // 0x10302a5
+    field public static final int Widget_Material_Light_Button_Borderless = 16974495; // 0x103029f
+    field public static final int Widget_Material_Light_Button_Borderless_Small = 16974496; // 0x10302a0
+    field public static final int Widget_Material_Light_Button_Inset = 16974497; // 0x10302a1
+    field public static final int Widget_Material_Light_Button_Small = 16974498; // 0x10302a2
+    field public static final int Widget_Material_Light_Button_Toggle = 16974499; // 0x10302a3
+    field public static final int Widget_Material_Light_CalendarView = 16974502; // 0x10302a6
+    field public static final int Widget_Material_Light_CheckedTextView = 16974503; // 0x10302a7
+    field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974504; // 0x10302a8
+    field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974505; // 0x10302a9
+    field public static final int Widget_Material_Light_CompoundButton_Star = 16974506; // 0x10302aa
+    field public static final int Widget_Material_Light_DropDownItem = 16974507; // 0x10302ab
+    field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974508; // 0x10302ac
+    field public static final int Widget_Material_Light_EditText = 16974509; // 0x10302ad
+    field public static final int Widget_Material_Light_ExpandableListView = 16974510; // 0x10302ae
+    field public static final int Widget_Material_Light_FastScroll = 16974511; // 0x10302af
+    field public static final int Widget_Material_Light_GridView = 16974512; // 0x10302b0
+    field public static final int Widget_Material_Light_HorizontalScrollView = 16974513; // 0x10302b1
+    field public static final int Widget_Material_Light_ImageButton = 16974514; // 0x10302b2
+    field public static final int Widget_Material_Light_ListPopupWindow = 16974515; // 0x10302b3
+    field public static final int Widget_Material_Light_ListView = 16974516; // 0x10302b4
+    field public static final int Widget_Material_Light_ListView_DropDown = 16974517; // 0x10302b5
+    field public static final int Widget_Material_Light_MediaRouteButton = 16974518; // 0x10302b6
+    field public static final int Widget_Material_Light_PopupMenu = 16974519; // 0x10302b7
+    field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974520; // 0x10302b8
+    field public static final int Widget_Material_Light_PopupWindow = 16974521; // 0x10302b9
+    field public static final int Widget_Material_Light_ProgressBar = 16974522; // 0x10302ba
+    field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974523; // 0x10302bb
+    field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974524; // 0x10302bc
+    field public static final int Widget_Material_Light_ProgressBar_Large = 16974525; // 0x10302bd
+    field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974526; // 0x10302be
+    field public static final int Widget_Material_Light_ProgressBar_Small = 16974527; // 0x10302bf
+    field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974528; // 0x10302c0
+    field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974529; // 0x10302c1
+    field public static final int Widget_Material_Light_RatingBar = 16974530; // 0x10302c2
+    field public static final int Widget_Material_Light_RatingBar_Indicator = 16974531; // 0x10302c3
+    field public static final int Widget_Material_Light_RatingBar_Small = 16974532; // 0x10302c4
+    field public static final int Widget_Material_Light_ScrollView = 16974533; // 0x10302c5
+    field public static final int Widget_Material_Light_SeekBar = 16974534; // 0x10302c6
+    field public static final int Widget_Material_Light_SegmentedButton = 16974535; // 0x10302c7
+    field public static final int Widget_Material_Light_Spinner = 16974537; // 0x10302c9
+    field public static final int Widget_Material_Light_StackView = 16974536; // 0x10302c8
+    field public static final int Widget_Material_Light_Tab = 16974538; // 0x10302ca
+    field public static final int Widget_Material_Light_TabWidget = 16974539; // 0x10302cb
+    field public static final int Widget_Material_Light_TextView = 16974540; // 0x10302cc
+    field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974541; // 0x10302cd
+    field public static final int Widget_Material_Light_WebTextView = 16974542; // 0x10302ce
+    field public static final int Widget_Material_Light_WebView = 16974543; // 0x10302cf
+    field public static final int Widget_Material_ListPopupWindow = 16974455; // 0x1030277
+    field public static final int Widget_Material_ListView = 16974456; // 0x1030278
+    field public static final int Widget_Material_ListView_DropDown = 16974457; // 0x1030279
+    field public static final int Widget_Material_MediaRouteButton = 16974458; // 0x103027a
+    field public static final int Widget_Material_PopupMenu = 16974459; // 0x103027b
+    field public static final int Widget_Material_PopupMenu_Overflow = 16974460; // 0x103027c
+    field public static final int Widget_Material_PopupWindow = 16974461; // 0x103027d
+    field public static final int Widget_Material_ProgressBar = 16974462; // 0x103027e
+    field public static final int Widget_Material_ProgressBar_Horizontal = 16974463; // 0x103027f
+    field public static final int Widget_Material_ProgressBar_Large = 16974464; // 0x1030280
+    field public static final int Widget_Material_ProgressBar_Small = 16974465; // 0x1030281
+    field public static final int Widget_Material_ProgressBar_Small_Title = 16974466; // 0x1030282
+    field public static final int Widget_Material_RatingBar = 16974467; // 0x1030283
+    field public static final int Widget_Material_RatingBar_Indicator = 16974468; // 0x1030284
+    field public static final int Widget_Material_RatingBar_Small = 16974469; // 0x1030285
+    field public static final int Widget_Material_ScrollView = 16974470; // 0x1030286
+    field public static final int Widget_Material_SeekBar = 16974471; // 0x1030287
+    field public static final int Widget_Material_SegmentedButton = 16974472; // 0x1030288
+    field public static final int Widget_Material_Spinner = 16974474; // 0x103028a
+    field public static final int Widget_Material_StackView = 16974473; // 0x1030289
+    field public static final int Widget_Material_Tab = 16974475; // 0x103028b
+    field public static final int Widget_Material_TabWidget = 16974476; // 0x103028c
+    field public static final int Widget_Material_TextView = 16974477; // 0x103028d
+    field public static final int Widget_Material_TextView_SpinnerItem = 16974478; // 0x103028e
+    field public static final int Widget_Material_Toolbar = 16974479; // 0x103028f
+    field public static final int Widget_Material_Toolbar_Button_Navigation = 16974480; // 0x1030290
+    field public static final int Widget_Material_WebTextView = 16974481; // 0x1030291
+    field public static final int Widget_Material_WebView = 16974482; // 0x1030292
     field public static final int Widget_PopupMenu = 16973958; // 0x1030086
     field public static final int Widget_PopupWindow = 16973878; // 0x1030036
     field public static final int Widget_ProgressBar = 16973852; // 0x103001c
@@ -2454,6 +2457,8 @@
     field public static final int Widget_TextView = 16973858; // 0x1030022
     field public static final int Widget_TextView_PopupMenu = 16973865; // 0x1030029
     field public static final int Widget_TextView_SpinnerItem = 16973866; // 0x103002a
+    field public static final int Widget_Toolbar = 16974339; // 0x1030203
+    field public static final int Widget_Toolbar_Button_Navigation = 16974340; // 0x1030204
     field public static final int Widget_WebView = 16973875; // 0x1030033
     field public static final int l_resource_pad1 = 16974336; // 0x1030200
     field public static final int l_resource_pad10 = 16974327; // 0x10301f7
@@ -3332,6 +3337,7 @@
     method public void openContextMenu(android.view.View);
     method public void openOptionsMenu();
     method public void overridePendingTransition(int, int);
+    method public void postponeEnterTransition();
     method public void recreate();
     method public void registerForContextMenu(android.view.View);
     method public final deprecated void removeDialog(int);
@@ -3387,6 +3393,7 @@
     method public deprecated void startManagingCursor(android.database.Cursor);
     method public boolean startNextMatchingActivity(android.content.Intent);
     method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
+    method public void startPostponedEnterTransition();
     method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
     method public void stopLockTask();
     method public deprecated void stopManagingCursor(android.database.Cursor);
@@ -5250,8 +5257,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 java.lang.String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME = "android.app.extra.defaultManagedProfileName";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.deviceAdminPackageName";
     field public static int FLAG_TO_MANAGED_PROFILE;
     field public static int FLAG_TO_PRIMARY_USER;
     field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
@@ -5356,23 +5363,9 @@
 
 }
 
-package android.app.maintenance {
+package android.app.job {
 
-  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.app.task {
-
-  public class Task implements android.os.Parcelable {
+  public class JobInfo implements android.os.Parcelable {
     method public int describeContents();
     method public int getBackoffPolicy();
     method public android.os.PersistableBundle getExtras();
@@ -5390,55 +5383,55 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public static abstract interface Task.BackoffPolicy {
+  public static abstract interface JobInfo.BackoffPolicy {
     field public static final int EXPONENTIAL = 1; // 0x1
     field public static final int LINEAR = 0; // 0x0
   }
 
-  public static final class Task.Builder {
-    ctor public Task.Builder(int, android.content.ComponentName);
-    method public android.app.task.Task build();
-    method public android.app.task.Task.Builder setBackoffCriteria(long, int);
-    method public android.app.task.Task.Builder setExtras(android.os.PersistableBundle);
-    method public android.app.task.Task.Builder setMinimumLatency(long);
-    method public android.app.task.Task.Builder setOverrideDeadline(long);
-    method public android.app.task.Task.Builder setPeriodic(long);
-    method public android.app.task.Task.Builder setRequiredNetworkCapabilities(int);
-    method public android.app.task.Task.Builder setRequiresCharging(boolean);
-    method public android.app.task.Task.Builder setRequiresDeviceIdle(boolean);
+  public static final class JobInfo.Builder {
+    ctor public JobInfo.Builder(int, android.content.ComponentName);
+    method public android.app.job.JobInfo build();
+    method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
+    method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
+    method public android.app.job.JobInfo.Builder setMinimumLatency(long);
+    method public android.app.job.JobInfo.Builder setOverrideDeadline(long);
+    method public android.app.job.JobInfo.Builder setPeriodic(long);
+    method public android.app.job.JobInfo.Builder setRequiredNetworkCapabilities(int);
+    method public android.app.job.JobInfo.Builder setRequiresCharging(boolean);
+    method public android.app.job.JobInfo.Builder setRequiresDeviceIdle(boolean);
   }
 
-  public static abstract interface Task.NetworkType {
+  public static abstract interface JobInfo.NetworkType {
     field public static final int ANY = 1; // 0x1
     field public static final int NONE = 0; // 0x0
     field public static final int UNMETERED = 2; // 0x2
   }
 
-  public abstract class TaskManager {
-    ctor public TaskManager();
-    method public abstract void cancel(int);
-    method public abstract void cancelAll();
-    method public abstract java.util.List<android.app.task.Task> getAllPendingTasks();
-    method public abstract int schedule(android.app.task.Task);
-    field public static final int RESULT_FAILURE = 0; // 0x0
-    field public static final int RESULT_SUCCESS = 1; // 0x1
-  }
-
-  public class TaskParams implements android.os.Parcelable {
+  public class JobParameters implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.PersistableBundle getExtras();
-    method public int getTaskId();
+    method public int getJobId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public abstract class TaskService extends android.app.Service {
-    ctor public TaskService();
+  public abstract class JobScheduler {
+    ctor public JobScheduler();
+    method public abstract void cancel(int);
+    method public abstract void cancelAll();
+    method public abstract java.util.List<android.app.job.JobInfo> getAllPendingJobs();
+    method public abstract int schedule(android.app.job.JobInfo);
+    field public static final int RESULT_FAILURE = 0; // 0x0
+    field public static final int RESULT_SUCCESS = 1; // 0x1
+  }
+
+  public abstract class JobService extends android.app.Service {
+    ctor public JobService();
+    method public final void jobFinished(android.app.job.JobParameters, boolean);
     method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract boolean onStartTask(android.app.task.TaskParams);
-    method public abstract boolean onStopTask(android.app.task.TaskParams);
-    method public final void taskFinished(android.app.task.TaskParams, boolean);
-    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_TASK_SERVICE";
+    method public abstract boolean onStartJob(android.app.job.JobParameters);
+    method public abstract boolean onStopJob(android.app.job.JobParameters);
+    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_JOB_SERVICE";
   }
 
 }
@@ -7006,6 +6999,7 @@
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
     field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
@@ -7026,7 +7020,6 @@
     field public static final java.lang.String SEARCH_SERVICE = "search";
     field public static final java.lang.String SENSOR_SERVICE = "sensor";
     field public static final java.lang.String STORAGE_SERVICE = "storage";
-    field public static final java.lang.String TASK_SERVICE = "task";
     field public static final java.lang.String TELEPHONY_SERVICE = "phone";
     field public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
     field public static final java.lang.String TV_INPUT_SERVICE = "tv_input";
@@ -8204,11 +8197,11 @@
   }
 
   public static abstract interface LauncherApps.OnAppsChangedListener {
-    method public abstract void onPackageAdded(java.lang.String, android.os.UserHandle);
-    method public abstract void onPackageChanged(java.lang.String, android.os.UserHandle);
-    method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle);
-    method public abstract void onPackagesAvailable(java.lang.String[], android.os.UserHandle, boolean);
-    method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public abstract void onPackageAdded(android.os.UserHandle, java.lang.String);
+    method public abstract void onPackageChanged(android.os.UserHandle, java.lang.String);
+    method public abstract void onPackageRemoved(android.os.UserHandle, java.lang.String);
+    method public abstract void onPackagesAvailable(android.os.UserHandle, java.lang.String[], boolean);
+    method public abstract void onPackagesUnavailable(android.os.UserHandle, java.lang.String[], boolean);
   }
 
   public class PackageInfo implements android.os.Parcelable {
@@ -11458,6 +11451,7 @@
 
   public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
     ctor public RippleDrawable(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+    method public void setColor(android.content.res.ColorStateList);
   }
 
   public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
@@ -15951,28 +15945,27 @@
     method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
     method public android.net.NetworkInfo getNetworkInfo(int);
     method public deprecated int getNetworkPreference();
+    method public static android.net.Network getProcessDefaultNetwork();
     method public boolean isActiveNetworkMetered();
-    method public boolean isNetworkActive();
+    method public boolean isDefaultNetworkActive();
     method public static boolean isNetworkTypeValid(int);
-    method public android.net.NetworkRequest listenForNetwork(android.net.NetworkCapabilities, android.net.ConnectivityManager.NetworkCallbackListener);
-    method public void registerNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
-    method public void releaseNetworkRequest(android.net.NetworkRequest);
+    method public void registerDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
+    method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
     method public void reportBadNetwork(android.net.Network);
-    method public android.net.NetworkRequest requestNetwork(android.net.NetworkCapabilities, android.net.ConnectivityManager.NetworkCallbackListener);
-    method public android.net.NetworkRequest requestNetwork(android.net.NetworkCapabilities, android.app.PendingIntent);
+    method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
     method public deprecated boolean requestRouteToHost(int, int);
     method public deprecated void setNetworkPreference(int);
+    method public static boolean setProcessDefaultNetwork(android.net.Network);
     method public deprecated int startUsingNetworkFeature(int, java.lang.String);
     method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
-    method public void unregisterNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
+    method public void unregisterDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
+    method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
     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
     field public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
     field public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover";
     field public static final deprecated java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
-    field public static final java.lang.String EXTRA_NETWORK_REQUEST_NETWORK = "networkRequestNetwork";
-    field public static final java.lang.String EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES = "networkRequestNetworkCapabilities";
     field public static final java.lang.String EXTRA_NETWORK_TYPE = "networkType";
     field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
     field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
@@ -15989,14 +15982,13 @@
     field public static final int TYPE_WIMAX = 6; // 0x6
   }
 
-  public static class ConnectivityManager.NetworkCallbackListener {
-    ctor public ConnectivityManager.NetworkCallbackListener();
-    method public void onAvailable(android.net.NetworkRequest, android.net.Network);
-    method public void onLinkPropertiesChanged(android.net.NetworkRequest, android.net.Network, android.net.LinkProperties);
-    method public void onLosing(android.net.NetworkRequest, android.net.Network, int);
-    method public void onLost(android.net.NetworkRequest, android.net.Network);
-    method public void onNetworkCapabilitiesChanged(android.net.NetworkRequest, android.net.Network, android.net.NetworkCapabilities);
-    method public void onReleased(android.net.NetworkRequest);
+  public static class ConnectivityManager.NetworkCallback {
+    ctor public ConnectivityManager.NetworkCallback();
+    method public void onAvailable(android.net.Network);
+    method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities);
+    method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
+    method public void onLosing(android.net.Network, int);
+    method public void onLost(android.net.Network);
   }
 
   public static abstract interface ConnectivityManager.OnNetworkActiveListener {
@@ -16023,46 +16015,34 @@
     field public int serverAddress;
   }
 
-  public class LinkAddress implements android.os.Parcelable {
+  public final class IpPrefix implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
-    method public int getFlags();
-    method public int getNetworkPrefixLength();
-    method public int getScope();
-    method public boolean isSameAddressAs(android.net.LinkAddress);
-    method public void writeToParcel(android.os.Parcel, int);
-  }
-
-  public class LinkProperties implements android.os.Parcelable {
-    ctor public LinkProperties();
-    ctor public LinkProperties(android.net.LinkProperties);
-    method public void addDns(java.net.InetAddress);
-    method public boolean addLinkAddress(android.net.LinkAddress);
-    method public void addRoute(android.net.RouteInfo);
-    method public void clear();
-    method public int describeContents();
-    method public java.util.Collection<java.lang.String> getAllInterfaceNames();
-    method public java.util.Collection<java.net.InetAddress> getDnses();
-    method public java.lang.String getDomains();
-    method public android.net.ProxyInfo getHttpProxy();
-    method public java.lang.String getInterfaceName();
-    method public java.util.Collection<android.net.LinkAddress> getLinkAddresses();
-    method public java.util.Collection<android.net.RouteInfo> getRoutes();
-    method public boolean hasIPv4Address();
-    method public boolean hasIPv6Address();
-    method public boolean removeLinkAddress(android.net.LinkAddress);
-    method public void setDomains(java.lang.String);
-    method public void setHttpProxy(android.net.ProxyInfo);
-    method public void setInterfaceName(java.lang.String);
-    method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>);
+    method public int getPrefixLength();
+    method public byte[] getRawAddress();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public static class LinkProperties.CompareResult {
-    ctor public LinkProperties.CompareResult();
-    field public java.util.Collection added;
-    field public java.util.Collection removed;
+  public class LinkAddress implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.net.InetAddress getAddress();
+    method public int getFlags();
+    method public int getPrefixLength();
+    method public int getScope();
+    method public void writeToParcel(android.os.Parcel, int);
+  }
+
+  public final class LinkProperties implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.util.List<java.net.InetAddress> getDnsServers();
+    method public java.lang.String getDomains();
+    method public android.net.ProxyInfo getHttpProxy();
+    method public java.lang.String getInterfaceName();
+    method public java.util.List<android.net.LinkAddress> getLinkAddresses();
+    method public java.util.List<android.net.RouteInfo> getRoutes();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
   public class LocalServerSocket {
@@ -16134,33 +16114,21 @@
   }
 
   public class Network implements android.os.Parcelable {
-    method public void bindProcess();
     method public int describeContents();
     method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
     method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException;
-    method public static android.net.Network getProcessBoundNetwork();
-    method public javax.net.SocketFactory socketFactory();
-    method public static void unbindProcess();
+    method public javax.net.SocketFactory getSocketFactory();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
-    ctor public NetworkCapabilities();
     ctor public NetworkCapabilities(android.net.NetworkCapabilities);
-    method public void addNetworkCapability(int);
-    method public void addTransportType(int);
     method public int describeContents();
     method public int getLinkDownstreamBandwidthKbps();
     method public int getLinkUpstreamBandwidthKbps();
-    method public java.util.Collection<java.lang.Integer> getNetworkCapabilities();
-    method public java.util.Collection<java.lang.Integer> getTransportTypes();
     method public boolean hasCapability(int);
     method public boolean hasTransport(int);
-    method public void removeNetworkCapability(int);
-    method public void removeTransportType(int);
-    method public void setLinkDownstreamBandwidthKbps(int);
-    method public void setLinkUpstreamBandwidthKbps(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int NET_CAPABILITY_CBS = 5; // 0x5
@@ -16234,7 +16202,15 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
-    field public final android.net.NetworkCapabilities networkCapabilities;
+  }
+
+  public static class NetworkRequest.Builder {
+    ctor public NetworkRequest.Builder();
+    method public android.net.NetworkRequest.Builder addCapability(int);
+    method public android.net.NetworkRequest.Builder addTransportType(int);
+    method public android.net.NetworkRequest build();
+    method public android.net.NetworkRequest.Builder removeCapability(int);
+    method public android.net.NetworkRequest.Builder removeTransportType(int);
   }
 
   public class ParseException extends java.lang.RuntimeException {
@@ -16263,18 +16239,15 @@
     method public void writeToParcel(android.os.Parcel, int);
   }
 
-  public class RouteInfo implements android.os.Parcelable {
-    ctor public RouteInfo(android.net.LinkAddress, java.net.InetAddress, java.lang.String);
-    ctor public RouteInfo(android.net.LinkAddress, java.net.InetAddress);
-    ctor public RouteInfo(java.net.InetAddress);
-    ctor public RouteInfo(android.net.LinkAddress);
+  public final class RouteInfo implements android.os.Parcelable {
     method public int describeContents();
-    method public android.net.LinkAddress getDestination();
+    method public android.net.IpPrefix getDestination();
     method public java.net.InetAddress getGateway();
     method public java.lang.String getInterface();
     method public boolean isDefaultRoute();
     method public boolean matches(java.net.InetAddress);
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
@@ -25838,21 +25811,28 @@
     method public final void cancelNotification(java.lang.String);
     method public final void cancelNotifications(java.lang.String[]);
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
-    method public android.service.notification.NotificationListenerService.Ranking getCurrentRanking();
+    method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onListenerConnected();
-    method public abstract void onNotificationPosted(android.service.notification.StatusBarNotification);
-    method public void onNotificationRankingUpdate();
-    method public abstract void onNotificationRemoved(android.service.notification.StatusBarNotification);
+    method public void onNotificationPosted(android.service.notification.StatusBarNotification);
+    method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
+    method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
+    method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
+    method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
   }
 
-  public static class NotificationListenerService.Ranking implements android.os.Parcelable {
+  public static class NotificationListenerService.Ranking {
+    method public java.lang.String getKey();
+    method public int getRank();
+    method public boolean isAmbient();
+    method public boolean isInterceptedByDoNotDisturb();
+  }
+
+  public static class NotificationListenerService.RankingMap implements android.os.Parcelable {
     method public int describeContents();
     method public java.lang.String[] getOrderedKeys();
-    method public int getRank(java.lang.String);
-    method public boolean isAmbient(java.lang.String);
-    method public boolean isInterceptedByDoNotDisturb(java.lang.String);
+    method public android.service.notification.NotificationListenerService.Ranking getRanking(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -26110,52 +26090,11 @@
 
 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);
   }
 
@@ -26171,18 +26110,7 @@
     method public java.lang.String getVariant();
   }
 
-  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 {
+  public 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);
@@ -26267,79 +26195,8 @@
     method public abstract void onUtteranceCompleted(java.lang.String);
   }
 
-  public 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();
@@ -26347,8 +26204,6 @@
     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 {
@@ -26358,44 +26213,6 @@
     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.system {
@@ -33914,15 +33731,15 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public static final class CursorAnchorInfo.CursorAnchorInfoBuilder {
-    ctor public CursorAnchorInfo.CursorAnchorInfoBuilder();
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder addCharacterRect(int, float, float, float, float);
+  public static final class CursorAnchorInfo.Builder {
+    ctor public CursorAnchorInfo.Builder();
+    method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterRect(int, float, float, float, float);
     method public android.view.inputmethod.CursorAnchorInfo build();
     method public void reset();
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setComposingText(int, java.lang.CharSequence);
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setInsertionMarkerLocation(float, float, float, float);
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setMatrix(android.graphics.Matrix);
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setSelectionRange(int, int);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, java.lang.CharSequence);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
   }
 
   public class EditorInfo implements android.text.InputType android.os.Parcelable {
@@ -34297,7 +34114,8 @@
 
 package android.webkit {
 
-  public abstract interface ClientCertRequest {
+  public abstract class ClientCertRequest {
+    ctor public ClientCertRequest();
     method public abstract void cancel();
     method public abstract java.lang.String getHost();
     method public abstract java.lang.String[] getKeyTypes();
@@ -39293,109 +39111,6 @@
     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);
@@ -41236,13 +40951,11 @@
     method public java.lang.String getValue();
     method public int getVersion();
     method public boolean hasExpired();
-    method public boolean isHttpOnly();
     method public static java.util.List<java.net.HttpCookie> parse(java.lang.String);
     method public void setComment(java.lang.String);
     method public void setCommentURL(java.lang.String);
     method public void setDiscard(boolean);
     method public void setDomain(java.lang.String);
-    method public void setHttpOnly(boolean);
     method public void setMaxAge(long);
     method public void setPath(java.lang.String);
     method public void setPortlist(java.lang.String);
@@ -41633,11 +41346,6 @@
     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;
@@ -41668,21 +41376,6 @@
     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;
@@ -41778,7 +41471,6 @@
     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();
@@ -41793,7 +41485,6 @@
     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;
@@ -42144,10 +41835,6 @@
 
 package java.nio.channels {
 
-  public class AlreadyBoundException extends java.lang.IllegalStateException {
-    ctor public AlreadyBoundException();
-  }
-
   public class AlreadyConnectedException extends java.lang.IllegalStateException {
     ctor public AlreadyConnectedException();
   }
@@ -42195,32 +41882,25 @@
     ctor public ConnectionPendingException();
   }
 
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.MulticastChannel java.nio.channels.ScatteringByteChannel {
+  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 java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method public java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress) throws java.io.IOException;
     method public static java.nio.channels.DatagramChannel open() throws java.io.IOException;
     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 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.GatheringByteChannel java.nio.channels.ScatteringByteChannel java.nio.channels.SeekableByteChannel {
+  public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
     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;
@@ -42252,7 +41932,6 @@
 
   public abstract class FileLock implements java.lang.AutoCloseable {
     ctor protected FileLock(java.nio.channels.FileChannel, long, long, boolean);
-    method public java.nio.channels.Channel acquiredBy();
     method public final java.nio.channels.FileChannel channel();
     method public final void close() throws java.io.IOException;
     method public final boolean isShared();
@@ -42285,32 +41964,6 @@
     method public abstract void close() throws java.io.IOException;
   }
 
-  public abstract class MembershipKey {
-    ctor protected MembershipKey();
-    method public abstract java.nio.channels.MembershipKey block(java.net.InetAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.MulticastChannel channel();
-    method public abstract void drop();
-    method public abstract java.net.InetAddress group();
-    method public abstract boolean isValid();
-    method public abstract java.net.NetworkInterface networkInterface();
-    method public abstract java.net.InetAddress sourceAddress();
-    method public abstract java.nio.channels.MembershipKey unblock(java.net.InetAddress);
-  }
-
-  public abstract interface MulticastChannel implements java.nio.channels.NetworkChannel {
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress) 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();
   }
@@ -42361,15 +42014,6 @@
     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();
@@ -42418,27 +42062,18 @@
     method public abstract java.nio.channels.Selector wakeup();
   }
 
-  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.NetworkChannel {
+  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel {
     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.NetworkChannel 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.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;
@@ -42446,9 +42081,7 @@
     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;
@@ -46408,7 +46041,6 @@
     method public java.lang.String getDisplayName(java.util.Locale);
     method public static java.util.Currency getInstance(java.lang.String);
     method public static java.util.Currency getInstance(java.util.Locale);
-    method public int getNumericCode();
     method public java.lang.String getSymbol();
     method public java.lang.String getSymbol(java.util.Locale);
   }
@@ -46693,13 +46325,6 @@
     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);
@@ -46814,7 +46439,6 @@
     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();
@@ -46824,24 +46448,15 @@
     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;
@@ -46859,33 +46474,14 @@
     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);
@@ -47572,35 +47168,6 @@
     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>);
@@ -47841,94 +47408,6 @@
     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;
@@ -48013,52 +47492,6 @@
     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);
@@ -48079,22 +47512,6 @@
     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);
@@ -48133,14 +47550,12 @@
     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 {
@@ -48186,15 +47601,6 @@
     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);
@@ -48282,14 +47688,6 @@
     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 {
@@ -48499,7 +47897,6 @@
     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();
@@ -48546,7 +47943,6 @@
     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();
@@ -49491,10 +48887,8 @@
 
   public class ZipFile implements java.io.Closeable {
     ctor public ZipFile(java.io.File) throws java.io.IOException, java.util.zip.ZipException;
-    ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException, java.util.zip.ZipException;
     ctor public ZipFile(java.lang.String) throws java.io.IOException;
     ctor public ZipFile(java.io.File, int) throws java.io.IOException;
-    ctor public ZipFile(java.io.File, int, java.nio.charset.Charset) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
     method public java.lang.String getComment();
@@ -49548,7 +48942,6 @@
 
   public class ZipInputStream extends java.util.zip.InflaterInputStream {
     ctor public ZipInputStream(java.io.InputStream);
-    ctor public ZipInputStream(java.io.InputStream, java.nio.charset.Charset);
     method public void closeEntry() throws java.io.IOException;
     method protected java.util.zip.ZipEntry createZipEntry(java.lang.String);
     method public java.util.zip.ZipEntry getNextEntry() throws java.io.IOException;
@@ -49596,7 +48989,6 @@
 
   public class ZipOutputStream extends java.util.zip.DeflaterOutputStream {
     ctor public ZipOutputStream(java.io.OutputStream);
-    ctor public ZipOutputStream(java.io.OutputStream, java.nio.charset.Charset);
     method public void closeEntry() throws java.io.IOException;
     method public void putNextEntry(java.util.zip.ZipEntry) throws java.io.IOException;
     method public void setComment(java.lang.String);
@@ -51095,7 +50487,6 @@
     method public abstract boolean getEnableSessionCreation();
     method public abstract java.lang.String[] getEnabledCipherSuites();
     method public abstract java.lang.String[] getEnabledProtocols();
-    method public javax.net.ssl.SSLSession getHandshakeSession();
     method public abstract javax.net.ssl.SSLEngineResult.HandshakeStatus getHandshakeStatus();
     method public abstract boolean getNeedClientAuth();
     method public java.lang.String getPeerHost();
@@ -51169,12 +50560,10 @@
     ctor public SSLParameters(java.lang.String[]);
     ctor public SSLParameters(java.lang.String[], java.lang.String[]);
     method public java.lang.String[] getCipherSuites();
-    method public java.lang.String getEndpointIdentificationAlgorithm();
     method public boolean getNeedClientAuth();
     method public java.lang.String[] getProtocols();
     method public boolean getWantClientAuth();
     method public void setCipherSuites(java.lang.String[]);
-    method public void setEndpointIdentificationAlgorithm(java.lang.String);
     method public void setNeedClientAuth(boolean);
     method public void setProtocols(java.lang.String[]);
     method public void setWantClientAuth(boolean);
@@ -51275,7 +50664,6 @@
     method public abstract boolean getEnableSessionCreation();
     method public abstract java.lang.String[] getEnabledCipherSuites();
     method public abstract java.lang.String[] getEnabledProtocols();
-    method public javax.net.ssl.SSLSession getHandshakeSession();
     method public abstract boolean getNeedClientAuth();
     method public javax.net.ssl.SSLParameters getSSLParameters();
     method public abstract javax.net.ssl.SSLSession getSession();
@@ -51331,14 +50719,6 @@
     method public java.lang.String chooseEngineServerAlias(java.lang.String, java.security.Principal[], javax.net.ssl.SSLEngine);
   }
 
-  public abstract class X509ExtendedTrustManager implements javax.net.ssl.X509TrustManager {
-    ctor public X509ExtendedTrustManager();
-    method public abstract void checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String, java.net.Socket) throws java.security.cert.CertificateException;
-    method public abstract void checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
-    method public abstract void checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, java.net.Socket) throws java.security.cert.CertificateException;
-    method public abstract void checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
-  }
-
   public abstract interface X509KeyManager implements javax.net.ssl.KeyManager {
     method public abstract java.lang.String chooseClientAlias(java.lang.String[], java.security.Principal[], java.net.Socket);
     method public abstract java.lang.String chooseServerAlias(java.lang.String, java.security.Principal[], java.net.Socket);
diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
index dce0a75..e6847a9 100644
--- a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
+++ b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
@@ -20,6 +20,7 @@
 import android.app.IActivityManager;
 import android.app.IActivityManager.ContentProviderHolder;
 import android.content.IContentProvider;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -33,7 +34,8 @@
     enum CommandVerb {
         UNSPECIFIED,
         GET,
-        PUT
+        PUT,
+        DELETE
     }
 
     static String[] mArgs;
@@ -74,6 +76,8 @@
                         mVerb = CommandVerb.GET;
                     } else if ("put".equalsIgnoreCase(arg)) {
                         mVerb = CommandVerb.PUT;
+                    } else if ("delete".equalsIgnoreCase(arg)) {
+                        mVerb = CommandVerb.DELETE;
                     } else {
                         // invalid
                         System.err.println("Invalid command: " + arg);
@@ -87,7 +91,7 @@
                         break;  // invalid
                     }
                     mTable = arg.toLowerCase();
-                } else if (mVerb == CommandVerb.GET) {
+                } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
                     mKey = arg;
                     if (mNextArg >= mArgs.length) {
                         valid = true;
@@ -136,6 +140,10 @@
                         case PUT:
                             putForUser(provider, mUser, mTable, mKey, mValue);
                             break;
+                        case DELETE:
+                            System.out.println("Deleted "
+                                    + deleteForUser(provider, mUser, mTable, mKey) + " rows");
+                            break;
                         default:
                             System.err.println("Unspecified command");
                             break;
@@ -211,9 +219,31 @@
         }
     }
 
+    int deleteForUser(IContentProvider provider, int userHandle,
+            final String table, final String key) {
+        Uri targetUri;
+        if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
+        else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
+        else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
+        else {
+            System.err.println("Invalid table; no delete performed");
+            throw new IllegalArgumentException("Invalid table " + table);
+        }
+
+        int num = 0;
+        try {
+            num = provider.delete(null, targetUri, null, null);
+        } catch (RemoteException e) {
+            System.err.println("Can't clear key " + key + " in " + table + " for user "
+                    + userHandle);
+        }
+        return num;
+    }
+
     private static void printUsage() {
         System.err.println("usage:  settings [--user NUM] get namespace key");
         System.err.println("        settings [--user NUM] put namespace key value");
+        System.err.println("        settings [--user NUM] delete namespace key");
         System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
         System.err.println("If '--user NUM' is not given, the operations are performed on the owner user.");
     }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 23b5f29..f6883e2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5326,7 +5326,8 @@
      *
      * @hide
      */
-    void convertToTranslucent(TranslucentConversionListener callback, ActivityOptions options) {
+    public void convertToTranslucent(TranslucentConversionListener callback, 
+            ActivityOptions options) {
         boolean drawComplete;
         try {
             mTranslucentCallback = callback;
@@ -5615,6 +5616,34 @@
         mExitTransitionListener = listener;
     }
 
+    /**
+     * Postpone the entering activity transition when Activity was started with
+     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.util.Pair[])}.
+     * <p>This method gives the Activity the ability to delay starting the entering and
+     * shared element transitions until all data is loaded. Until then, the Activity won't
+     * draw into its window, leaving the window transparent. This may also cause the
+     * returning animation to be delayed until data is ready. This method should be
+     * called in {@link #onCreate(android.os.Bundle)} or in
+     * {@link #onActivityReenter(int, android.content.Intent)}.
+     * {@link #startPostponedEnterTransition()} must be called to allow the Activity to
+     * start the transitions. If the Activity did not use
+     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.util.Pair[])}, then this method does nothing.</p>
+     */
+    public void postponeEnterTransition() {
+        mActivityTransitionState.postponeEnterTransition();
+    }
+
+    /**
+     * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
+     * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
+     * to have your Activity start drawing.
+     */
+    public void startPostponedEnterTransition() {
+        mActivityTransitionState.startPostponedEnterTransition();
+    }
+
     // ------------------ Internal API ------------------
     
     final void setParent(Activity parent) {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index b658597..703df51 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -214,11 +214,21 @@
             ArrayList<String> allSharedElementNames,
             ArrayList<String> accepted, ArrayList<String> localNames,
             SharedElementListener listener, boolean isReturning) {
+        this(window, allSharedElementNames, listener, isReturning);
+        viewsReady(accepted, localNames);
+    }
+
+    public ActivityTransitionCoordinator(Window window,
+            ArrayList<String> allSharedElementNames,
+            SharedElementListener listener, boolean isReturning) {
         super(new Handler());
         mWindow = window;
         mListener = listener;
         mAllSharedElementNames = allSharedElementNames;
         mIsReturning = isReturning;
+    }
+
+    protected void viewsReady(ArrayList<String> accepted, ArrayList<String> localNames) {
         setSharedElements(accepted, localNames);
         if (getViewsTransition() != null) {
             getDecor().captureTransitioningViews(mTransitioningViews);
@@ -274,6 +284,8 @@
         return names;
     }
 
+    public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; }
+
     public static void setViewVisibility(Collection<View> views, int visibility) {
         if (views != null) {
             for (View view : views) {
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index b32e9ad..d94dadda 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -87,6 +87,11 @@
      */
     private boolean mHasExited;
 
+    /**
+     * Postpone painting and starting the enter transition until this is false.
+     */
+    private boolean mIsEnterPostponed;
+
     public ActivityTransitionState() {
     }
 
@@ -140,15 +145,38 @@
         if (mEnterActivityOptions.isReturning()) {
             restoreExitedViews();
             activity.getWindow().getDecorView().setVisibility(View.VISIBLE);
-            mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
-                    resultReceiver, sharedElementNames, mExitingFrom, mExitingTo);
+        }
+        mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
+                resultReceiver, sharedElementNames, mEnterActivityOptions.isReturning());
+
+        if (!mIsEnterPostponed) {
+            startEnter();
+        }
+    }
+
+    public void postponeEnterTransition() {
+        mIsEnterPostponed = true;
+    }
+
+    public void startPostponedEnterTransition() {
+        if (mIsEnterPostponed) {
+            mIsEnterPostponed = false;
+            if (mEnterTransitionCoordinator != null) {
+                startEnter();
+            }
+        }
+    }
+
+    private void startEnter() {
+        if (mEnterActivityOptions.isReturning()) {
+            mEnterTransitionCoordinator.viewsReady(mExitingFrom, mExitingTo);
         } else {
-            mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
-                    resultReceiver, sharedElementNames, null, null);
-            mEnteringNames = sharedElementNames;
+            mEnterTransitionCoordinator.viewsReady(null, null);
+            mEnteringNames = mEnterTransitionCoordinator.getAllSharedElementNames();
             mEnteringFrom = mEnterTransitionCoordinator.getAcceptedNames();
             mEnteringTo = mEnterTransitionCoordinator.getMappedNames();
         }
+
         mExitingFrom = null;
         mExitingTo = null;
         mEnterActivityOptions = null;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5bbc43c..c5190d3 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -133,7 +133,7 @@
 import android.accounts.AccountManager;
 import android.accounts.IAccountManager;
 import android.app.admin.DevicePolicyManager;
-import android.app.task.ITaskManager;
+import android.app.job.IJobScheduler;
 import android.app.trust.TrustManager;
 
 import com.android.internal.annotations.GuardedBy;
@@ -697,10 +697,10 @@
                 return new UsageStatsManager(ctx.getOuterContext());
         }});
 
-        registerService(TASK_SERVICE, new ServiceFetcher() {
+        registerService(JOB_SCHEDULER_SERVICE, new ServiceFetcher() {
             public Object createService(ContextImpl ctx) {
-                IBinder b = ServiceManager.getService(TASK_SERVICE);
-                return new TaskManagerImpl(ITaskManager.Stub.asInterface(b));
+                IBinder b = ServiceManager.getService(JOB_SCHEDULER_SERVICE);
+                return new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b));
             }});
     }
 
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 4b052e7..779e3de 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -53,18 +53,37 @@
     private boolean mIsCanceled;
     private ObjectAnimator mBackgroundAnimator;
     private boolean mIsExitTransitionComplete;
+    private boolean mIsReadyForTransition;
+    private Bundle mSharedElementsBundle;
 
     public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
-            ArrayList<String> sharedElementNames,
-            ArrayList<String> acceptedNames, ArrayList<String> mappedNames) {
-        super(activity.getWindow(), sharedElementNames, acceptedNames, mappedNames,
-                getListener(activity, acceptedNames), acceptedNames != null);
+            ArrayList<String> sharedElementNames, boolean isReturning) {
+        super(activity.getWindow(), sharedElementNames,
+                getListener(activity, isReturning), isReturning);
         mActivity = activity;
         setResultReceiver(resultReceiver);
         prepareEnter();
         Bundle resultReceiverBundle = new Bundle();
         resultReceiverBundle.putParcelable(KEY_REMOTE_RECEIVER, this);
         mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
+        getDecor().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                if (mIsReadyForTransition) {
+                    getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
+                }
+                return mIsReadyForTransition;
+            }
+        });
+    }
+
+    public void viewsReady(ArrayList<String> accepted, ArrayList<String> localNames) {
+        if (mIsReadyForTransition) {
+            return;
+        }
+        super.viewsReady(accepted, localNames);
+
+        mIsReadyForTransition = true;
         if (mIsReturning) {
             mHandler = new Handler() {
                 @Override
@@ -75,6 +94,13 @@
             mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
             send(MSG_SEND_SHARED_ELEMENT_DESTINATION, null);
         }
+        setViewVisibility(mSharedElements, View.INVISIBLE);
+        if (getViewsTransition() != null) {
+            setViewVisibility(mTransitioningViews, View.INVISIBLE);
+        }
+        if (mSharedElementsBundle != null) {
+            onTakeSharedElements();
+        }
     }
 
     private void sendSharedElementDestination() {
@@ -94,9 +120,7 @@
         }
     }
 
-    private static SharedElementListener getListener(Activity activity,
-            ArrayList<String> acceptedNames) {
-        boolean isReturning = acceptedNames != null;
+    private static SharedElementListener getListener(Activity activity, boolean isReturning) {
         return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
     }
 
@@ -108,7 +132,8 @@
                     if (mHandler != null) {
                         mHandler.removeMessages(MSG_CANCEL);
                     }
-                    onTakeSharedElements(resultData);
+                    mSharedElementsBundle = resultData;
+                    onTakeSharedElements();
                 }
                 break;
             case MSG_EXIT_TRANSITION_COMPLETE:
@@ -139,7 +164,7 @@
             mSharedElementNames.clear();
             mSharedElements.clear();
             mAllSharedElementNames.clear();
-            onTakeSharedElements(null);
+            startSharedElementTransition(null);
             onRemoteExitTransitionComplete();
         }
     }
@@ -149,10 +174,6 @@
     }
 
     protected void prepareEnter() {
-        setViewVisibility(mSharedElements, View.INVISIBLE);
-        if (getViewsTransition() != null) {
-            setViewVisibility(mTransitioningViews, View.INVISIBLE);
-        }
         mActivity.overridePendingTransition(0, 0);
         if (!mIsReturning) {
             mActivity.convertToTranslucent(null, null);
@@ -185,7 +206,25 @@
         }
     }
 
-    protected void onTakeSharedElements(Bundle sharedElementState) {
+    protected void onTakeSharedElements() {
+        if (!mIsReadyForTransition || mSharedElementsBundle == null) {
+            return;
+        }
+        final Bundle sharedElementState = mSharedElementsBundle;
+        mSharedElementsBundle = null;
+        getDecor().getViewTreeObserver()
+                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
+                        startSharedElementTransition(sharedElementState);
+                        return false;
+                    }
+                });
+        getDecor().invalidate();
+    }
+
+    private void startSharedElementTransition(Bundle sharedElementState) {
         setEpicenter();
         // Remove rejected shared elements
         ArrayList<String> rejectedNames = new ArrayList<String>(mAllSharedElementNames);
@@ -299,8 +338,8 @@
     }
 
     public void stop() {
+        makeOpaque();
         mHasStopped = true;
-        mActivity = null;
         mIsCanceled = true;
         mResultReceiver = null;
         if (mBackgroundAnimator != null) {
@@ -310,7 +349,7 @@
     }
 
     private void makeOpaque() {
-        if (!mHasStopped) {
+        if (!mHasStopped && mActivity != null) {
             mActivity.convertFromTranslucent();
             mActivity = null;
         }
diff --git a/core/java/android/app/TaskManagerImpl.java b/core/java/android/app/JobSchedulerImpl.java
similarity index 67%
rename from core/java/android/app/TaskManagerImpl.java
rename to core/java/android/app/JobSchedulerImpl.java
index fe29fb7..09038d5 100644
--- a/core/java/android/app/TaskManagerImpl.java
+++ b/core/java/android/app/JobSchedulerImpl.java
@@ -17,38 +17,38 @@
 // in android.app so ContextImpl has package access
 package android.app;
 
-import android.app.task.ITaskManager;
-import android.app.task.Task;
-import android.app.task.TaskManager;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.IJobScheduler;
 import android.os.RemoteException;
 
 import java.util.List;
 
 
 /**
- * Concrete implementation of the TaskManager interface
+ * Concrete implementation of the JobScheduler interface
  * @hide 
  */
-public class TaskManagerImpl extends TaskManager {
-    ITaskManager mBinder;
+public class JobSchedulerImpl extends JobScheduler {
+    IJobScheduler mBinder;
 
-    /* package */ TaskManagerImpl(ITaskManager binder) {
+    /* package */ JobSchedulerImpl(IJobScheduler binder) {
         mBinder = binder;
     }
 
     @Override
-    public int schedule(Task task) {
+    public int schedule(JobInfo job) {
         try {
-            return mBinder.schedule(task);
+            return mBinder.schedule(job);
         } catch (RemoteException e) {
-            return TaskManager.RESULT_FAILURE;
+            return JobScheduler.RESULT_FAILURE;
         }
     }
 
     @Override
-    public void cancel(int taskId) {
+    public void cancel(int jobId) {
         try {
-            mBinder.cancel(taskId);
+            mBinder.cancel(jobId);
         } catch (RemoteException e) {}
 
     }
@@ -62,9 +62,9 @@
     }
 
     @Override
-    public List<Task> getAllPendingTasks() {
+    public List<JobInfo> getAllPendingJobs() {
         try {
-            return mBinder.getAllPendingTasks();
+            return mBinder.getAllPendingJobs();
         } catch (RemoteException e) {
             return null;
         }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a1cdf59..55abdb6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -23,7 +23,6 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
@@ -31,7 +30,6 @@
 import android.media.session.MediaSessionToken;
 import android.net.Uri;
 import android.os.BadParcelableException;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -2568,7 +2566,7 @@
                     R.id.icon,
                     true,
                     -1,
-                    mColor,
+                    resolveColor(),
                     PorterDuff.Mode.SRC_ATOP,
                     -1);
         }
@@ -2595,17 +2593,22 @@
                         R.id.right_icon,
                         true,
                         -1,
-                        mColor,
+                        resolveColor(),
                         PorterDuff.Mode.SRC_ATOP,
                         -1);
             }
         }
 
+        private int sanitizeColor() {
+            if (mColor != COLOR_DEFAULT) {
+                mColor |= 0xFF000000; // no alpha for custom colors
+            }
+            return mColor;
+        }
+
         private int resolveColor() {
             if (mColor == COLOR_DEFAULT) {
-                mColor = mContext.getResources().getColor(R.color.notification_icon_bg_color);
-            } else {
-                mColor |= 0xFF000000; // no alpha for custom colors
+                return mContext.getResources().getColor(R.color.notification_icon_bg_color);
             }
             return mColor;
         }
@@ -2621,7 +2624,7 @@
             n.iconLevel = mSmallIconLevel;
             n.number = mNumber;
 
-            n.color = resolveColor();
+            n.color = sanitizeColor();
 
             n.contentView = makeContentView();
             n.contentIntent = mContentIntent;
@@ -3616,14 +3619,16 @@
          *         .build();</pre>
          *
          * <p>The activity to launch needs to allow embedding, must be exported, and
-         * should have an empty task affinity.
+         * should have an empty task affinity. It is also recommended to use the device
+         * default light theme.
          *
          * <p>Example AndroidManifest.xml entry:
          * <pre class="prettyprint">
          * &lt;activity android:name=&quot;com.example.MyDisplayActivity&quot;
          *     android:exported=&quot;true&quot;
          *     android:allowEmbedded=&quot;true&quot;
-         *     android:taskAffinity=&quot;&quot; /&gt;</pre>
+         *     android:taskAffinity=&quot;&quot;
+         *     android:theme=&quot;@android:style/Theme.DeviceDefault.Light&quot; /&gt;</pre>
          *
          * @param intent the {@link PendingIntent} for an activity
          * @return this object for method chaining
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 85e970c..0d947217 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -293,7 +293,7 @@
 
         IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
                 IVoiceInteractorCallback callback) throws RemoteException {
-            return interactor.startConfirmation(packageName, callback, mCommand, mArgs);
+            return interactor.startCommand(packageName, callback, mCommand, mArgs);
         }
    }
 
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index ee222a9..1015514 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -16,6 +16,7 @@
 
 package android.app.admin;
 
+import android.accounts.AccountManager;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Service;
@@ -165,12 +166,14 @@
             = "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. It is used in both the
-     * Profile Owner and the Device Owner provisioning.
+     * Broadcast Action: This broadcast is sent to indicate that provisioning of a managed profile
+     * or managed device has completed successfully.
      *
-     * <p>The broadcast is limited to the DeviceAdminReceiver component specified in the message
-     * that started the provisioning. It is also limited to the managed profile.
+     * <p>The broadcast is limited to the profile that will be managed by the application that
+     * requested provisioning. In the device owner case the profile is the primary user.
+     * The broadcast will also be limited to the {@link DeviceAdminReceiver} component
+     * specified in the original intent or NFC bump that started the provisioning process
+     * (@see DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE).
      *
      * <p>Input: Nothing.</p>
      * <p>Output: Nothing</p>
@@ -307,18 +310,23 @@
     }
 
     /**
-     * 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.
+     * Called when provisioning of a managed profile or managed device has completed successfully.
      *
-     * <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> As a prerequisit for the execution of this callback the (@link DeviceAdminReceiver} has
+     * to declare an intent filter for {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}.
+     * Its component must also be specified in the {@link DevicePolicyManager#EXTRA_DEVICE_ADMIN}
+     * of the {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the
+     * managed provisioning.
      *
-     * <p>Provisioning can be triggered via an intent with the action
-     * android.managedprovisioning.ACTION_PROVISION_MANAGED_PROFILE.
+     * <p>When provisioning is complete, the managed profile is hidden until the profile owner
+     * calls {DevicePolicyManager#setProfileEnabled(ComponentName admin)}. Typically a profile
+     * owner will enable the profile when it has finished any additional setup such as adding an
+     * account by using the {@link AccountManager} and calling apis to bring the profile into the
+     * desired state.
+     *
+     * <p> Note that provisioning completes without waiting for any server interactions, so the
+     * profile owner needs to wait for data to be available if required (e.g android device ids or
+     * other data that is set as a result of server interactions).
      *
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d725873..157b8ec 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -82,17 +82,25 @@
 
     /**
      * 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>A managed profile allows data separation for example for the usage of a
+     * device as a personal and corporate device. The user which provisioning is started from and
+     * the managed profile share a launcher.
+     *
+     * <p>This intent will typically be sent by a mobile device management application (mdm).
+     * Provisioning adds a managed profile and sets the mdm as the profile owner who has full
+     * control over the profile
+     *
+     * <p>This intent must contain the extras {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}
+     * {@link #EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME} and {@link #EXTRA_DEVICE_ADMIN}.
      *
      * <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.
+     * managed profile. The intent is sent to the {@link DeviceAdminReceiver} specified in the
+     * {@link #EXTRA_DEVICE_ADMIN} exclusively.
+     *
+     * If provisioning fails, the managedProfile is removed so the device returns to its previous
+     * state.
      *
      * <p>Input: Nothing.</p>
      * <p>Output: Nothing</p>
@@ -107,7 +115,7 @@
      * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}.
      */
     public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
-        = "deviceAdminPackageName";
+        = "android.app.extra.deviceAdminPackageName";
 
     /**
      * A String extra holding the default name of the profile that is created during managed profile
@@ -115,7 +123,7 @@
      * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}
      */
     public static final String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME
-        = "defaultManagedProfileName";
+        = "android.app.extra.defaultManagedProfileName";
 
     /**
      * Activity action: ask the user to add a new device administrator to the system.
@@ -837,6 +845,9 @@
      * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to be able to call this
      * method; if it has not, a security exception will be thrown.
      *
+     * <p> Note that setting the password will automatically reset the expiration time for all
+     * active admins. Active admins do not need to explicitly call this method in that case.
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param timeout The limit (in ms) that a password can remain in effect. A value of 0
      *        means there is no restriction (unlimited).
diff --git a/core/java/android/app/job/IJobCallback.aidl b/core/java/android/app/job/IJobCallback.aidl
new file mode 100644
index 0000000..2d3948f
--- /dev/null
+++ b/core/java/android/app/job/IJobCallback.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.job;
+
+/**
+ * The server side of the JobScheduler 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 Job Service instance is reporting.
+ *
+ * {@hide}
+ */
+interface IJobCallback {
+    /**
+     * Immediate callback to the system after sending a start signal, used to quickly detect ANR.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param ongoing True to indicate that the client is processing the job. False if the job is
+     * complete
+     */
+    void acknowledgeStartMessage(int jobId, boolean ongoing);
+    /**
+     * Immediate callback to the system after sending a stop signal, used to quickly detect ANR.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param reschedule Whether or not to reschedule this job.
+     */
+    void acknowledgeStopMessage(int jobId, boolean reschedule);
+    /*
+     * Tell the job manager that the client is done with its execution, so that it can go on to
+     * the next one and stop attributing wakelock time to us etc.
+     *
+     * @param jobId Unique integer used to identify this job.
+     * @param reschedule Whether or not to reschedule this job.
+     */
+    void jobFinished(int jobId, boolean reschedule);
+}
diff --git a/core/java/android/app/task/ITaskManager.aidl b/core/java/android/app/job/IJobScheduler.aidl
similarity index 71%
rename from core/java/android/app/task/ITaskManager.aidl
rename to core/java/android/app/job/IJobScheduler.aidl
index b56c78a..f1258ae 100644
--- a/core/java/android/app/task/ITaskManager.aidl
+++ b/core/java/android/app/job/IJobScheduler.aidl
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-import android.app.task.Task;
+import android.app.job.JobInfo;
 
  /**
-  * IPC interface that supports the app-facing {@link #TaskManager} api.
+  * IPC interface that supports the app-facing {@link #JobScheduler} api.
   * {@hide}
   */
-interface ITaskManager {
-    int schedule(in Task task);
-    void cancel(int taskId);
+interface IJobScheduler {
+    int schedule(in JobInfo job);
+    void cancel(int jobId);
     void cancelAll();
-    List<Task> getAllPendingTasks();
+    List<JobInfo> getAllPendingJobs();
 }
diff --git a/core/java/android/app/task/ITaskService.aidl b/core/java/android/app/job/IJobService.aidl
similarity index 62%
rename from core/java/android/app/task/ITaskService.aidl
rename to core/java/android/app/job/IJobService.aidl
index 87b0191..63f8b81 100644
--- a/core/java/android/app/task/ITaskService.aidl
+++ b/core/java/android/app/job/IJobService.aidl
@@ -14,22 +14,19 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-import android.app.task.ITaskCallback;
-import android.app.task.TaskParams;
-
-import android.os.Bundle;
+import android.app.job.JobParameters;
 
 /**
  * Interface that the framework uses to communicate with application code that implements a
- * TaskService.  End user code does not implement this interface directly; instead, the app's
- * service implementation will extend android.app.task.TaskService.
+ * JobService.  End user code does not implement this interface directly; instead, the app's
+ * service implementation will extend android.app.job.JobService.
  * {@hide}
  */
-oneway interface ITaskService {
-    /** Begin execution of application's task. */
-    void startTask(in TaskParams taskParams);
+oneway interface IJobService {
+    /** Begin execution of application's job. */
+    void startJob(in JobParameters jobParams);
     /** Stop execution of application's task. */
-    void stopTask(in TaskParams taskParams);
+    void stopJob(in JobParameters jobParams);
 }
diff --git a/core/java/android/app/task/Task.aidl b/core/java/android/app/job/JobInfo.aidl
similarity index 92%
rename from core/java/android/app/task/Task.aidl
rename to core/java/android/app/job/JobInfo.aidl
index 1f25439..7b198a8 100644
--- a/core/java/android/app/task/Task.aidl
+++ b/core/java/android/app/job/JobInfo.aidl
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-parcelable Task;
- 
\ No newline at end of file
+parcelable JobInfo;
diff --git a/core/java/android/app/task/Task.java b/core/java/android/app/job/JobInfo.java
similarity index 74%
rename from core/java/android/app/task/Task.java
rename to core/java/android/app/job/JobInfo.java
index 0e660b3..a22e4cd 100644
--- a/core/java/android/app/task/Task.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.app.task;
+package android.app.job;
 
 import android.content.ComponentName;
 import android.os.Bundle;
@@ -23,22 +23,22 @@
 import android.os.PersistableBundle;
 
 /**
- * Container of data passed to the {@link android.app.task.TaskManager} fully encapsulating the
+ * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
  * parameters required to schedule work against the calling application. These are constructed
- * using the {@link Task.Builder}.
+ * using the {@link JobInfo.Builder}.
  */
-public class Task implements Parcelable {
+public class JobInfo implements Parcelable {
     public interface NetworkType {
         /** Default. */
         public final int NONE = 0;
-        /** This task requires network connectivity. */
+        /** This job requires network connectivity. */
         public final int ANY = 1;
-        /** This task requires network connectivity that is unmetered. */
+        /** This job requires network connectivity that is unmetered. */
         public final int UNMETERED = 2;
     }
 
     /**
-     * Amount of backoff a task has initially by default, in milliseconds.
+     * Amount of backoff a job has initially by default, in milliseconds.
      * @hide.
      */
     public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 5000L;
@@ -63,7 +63,7 @@
         public final int EXPONENTIAL = 1;
     }
 
-    private final int taskId;
+    private final int jobId;
     // TODO: Change this to use PersistableBundle when that lands in master.
     private final PersistableBundle extras;
     private final ComponentName service;
@@ -80,10 +80,10 @@
     private final int backoffPolicy;
 
     /**
-     * Unique task id associated with this class. This is assigned to your task by the scheduler.
+     * Unique job id associated with this class. This is assigned to your job by the scheduler.
      */
     public int getId() {
-        return taskId;
+        return jobId;
     }
 
     /**
@@ -94,43 +94,43 @@
     }
 
     /**
-     * Name of the service endpoint that will be called back into by the TaskManager.
+     * Name of the service endpoint that will be called back into by the JobScheduler.
      */
     public ComponentName getService() {
         return service;
     }
 
     /**
-     * Whether this task needs the device to be plugged in.
+     * Whether this job needs the device to be plugged in.
      */
     public boolean isRequireCharging() {
         return requireCharging;
     }
 
     /**
-     * Whether this task needs the device to be in an Idle maintenance window.
+     * Whether this job needs the device to be in an Idle maintenance window.
      */
     public boolean isRequireDeviceIdle() {
         return requireDeviceIdle;
     }
 
     /**
-     * See {@link android.app.task.Task.NetworkType} for a description of this value.
+     * See {@link android.app.job.JobInfo.NetworkType} for a description of this value.
      */
     public int getNetworkCapabilities() {
         return networkCapabilities;
     }
 
     /**
-     * Set for a task that does not recur periodically, to specify a delay after which the task
-     * will be eligible for execution. This value is not set if the task recurs periodically.
+     * Set for a job that does not recur periodically, to specify a delay after which the job
+     * will be eligible for execution. This value is not set if the job recurs periodically.
      */
     public long getMinLatencyMillis() {
         return minLatencyMillis;
     }
 
     /**
-     * See {@link Builder#setOverrideDeadline(long)}. This value is not set if the task recurs
+     * See {@link Builder#setOverrideDeadline(long)}. This value is not set if the job recurs
      * periodically.
      */
     public long getMaxExecutionDelayMillis() {
@@ -138,23 +138,23 @@
     }
 
     /**
-     * Track whether this task will repeat with a given period.
+     * Track whether this job will repeat with a given period.
      */
     public boolean isPeriodic() {
         return isPeriodic;
     }
 
     /**
-     * Set to the interval between occurrences of this task. This value is <b>not</b> set if the
-     * task does not recur periodically.
+     * Set to the interval between occurrences of this job. This value is <b>not</b> set if the
+     * job does not recur periodically.
      */
     public long getIntervalMillis() {
         return intervalMillis;
     }
 
     /**
-     * The amount of time the TaskManager will wait before rescheduling a failed task. This value
-     * will be increased depending on the backoff policy specified at task creation time. Defaults
+     * The amount of time the JobScheduler will wait before rescheduling a failed job. This value
+     * will be increased depending on the backoff policy specified at job creation time. Defaults
      * to 5 seconds.
      */
     public long getInitialBackoffMillis() {
@@ -162,7 +162,7 @@
     }
 
     /**
-     * See {@link android.app.task.Task.BackoffPolicy} for an explanation of the values this field
+     * See {@link android.app.job.JobInfo.BackoffPolicy} for an explanation of the values this field
      * can take. This defaults to exponential.
      */
     public int getBackoffPolicy() {
@@ -187,8 +187,8 @@
         return hasLateConstraint;
     }
 
-    private Task(Parcel in) {
-        taskId = in.readInt();
+    private JobInfo(Parcel in) {
+        jobId = in.readInt();
         extras = in.readPersistableBundle();
         service = in.readParcelable(null);
         requireCharging = in.readInt() == 1;
@@ -204,10 +204,10 @@
         hasLateConstraint = in.readInt() == 1;
     }
 
-    private Task(Task.Builder b) {
-        taskId = b.mTaskId;
+    private JobInfo(JobInfo.Builder b) {
+        jobId = b.mJobId;
         extras = b.mExtras;
-        service = b.mTaskService;
+        service = b.mJobService;
         requireCharging = b.mRequiresCharging;
         requireDeviceIdle = b.mRequiresDeviceIdle;
         networkCapabilities = b.mNetworkCapabilities;
@@ -228,7 +228,7 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(taskId);
+        out.writeInt(jobId);
         out.writePersistableBundle(extras);
         out.writeParcelable(service, flags);
         out.writeInt(requireCharging ? 1 : 0);
@@ -244,23 +244,23 @@
         out.writeInt(hasLateConstraint ? 1 : 0);
     }
 
-    public static final Creator<Task> CREATOR = new Creator<Task>() {
+    public static final Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
         @Override
-        public Task createFromParcel(Parcel in) {
-            return new Task(in);
+        public JobInfo createFromParcel(Parcel in) {
+            return new JobInfo(in);
         }
 
         @Override
-        public Task[] newArray(int size) {
-            return new Task[size];
+        public JobInfo[] newArray(int size) {
+            return new JobInfo[size];
         }
     };
 
-    /** Builder class for constructing {@link Task} objects. */
+    /** Builder class for constructing {@link JobInfo} objects. */
     public static final class Builder {
-        private int mTaskId;
+        private int mJobId;
         private PersistableBundle mExtras = PersistableBundle.EMPTY;
-        private ComponentName mTaskService;
+        private ComponentName mJobService;
         // Requirements.
         private boolean mRequiresCharging;
         private boolean mRequiresDeviceIdle;
@@ -280,15 +280,15 @@
         private boolean mBackoffPolicySet = false;
 
         /**
-         * @param taskId Application-provided id for this task. Subsequent calls to cancel, or
-         *               tasks created with the same taskId, will update the pre-existing task with
+         * @param jobId Application-provided id for this job. Subsequent calls to cancel, or
+         *               jobs created with the same jobId, will update the pre-existing job with
          *               the same id.
-         * @param taskService The endpoint that you implement that will receive the callback from the
-         *            TaskManager.
+         * @param jobService The endpoint that you implement that will receive the callback from the
+         *            JobScheduler.
          */
-        public Builder(int taskId, ComponentName taskService) {
-            mTaskService = taskService;
-            mTaskId = taskId;
+        public Builder(int jobId, ComponentName jobService) {
+            mJobService = jobService;
+            mJobId = jobId;
         }
 
         /**
@@ -302,10 +302,10 @@
 
         /**
          * Set some description of the kind of network capabilities you would like to have. This
-         * will be a parameter defined in {@link android.app.task.Task.NetworkType}.
+         * will be a parameter defined in {@link android.app.job.JobInfo.NetworkType}.
          * Not calling this function means the network is not necessary.
          * Bear in mind that calling this function defines network as a strict requirement for your
-         * task if the network requested is not available your task will never run. See
+         * job if the network requested is not available your job will never run. See
          * {@link #setOverrideDeadline(long)} to change this behaviour.
          */
         public Builder setRequiredNetworkCapabilities(int networkCapabilities) {
@@ -313,10 +313,10 @@
             return this;
         }
 
-        /*
-         * Specify that to run this task, the device needs to be plugged in. This defaults to
+        /**
+         * Specify that to run this job, the device needs to be plugged in. This defaults to
          * false.
-         * @param requireCharging Whether or not the device is plugged in.
+         * @param requiresCharging Whether or not the device is plugged in.
          */
         public Builder setRequiresCharging(boolean requiresCharging) {
             mRequiresCharging = requiresCharging;
@@ -324,11 +324,11 @@
         }
 
         /**
-         * Specify that to run, the task needs the device to be in idle mode. This defaults to
+         * Specify that to run, the job needs the device to be in idle mode. This defaults to
          * false.
          * <p>Idle mode is a loose definition provided by the system, which means that the device
          * is not in use, and has not been in use for some time. As such, it is a good time to
-         * perform resource heavy tasks. Bear in mind that battery usage will still be attributed
+         * perform resource heavy jobs. Bear in mind that battery usage will still be attributed
          * to your application, and surfaced to the user in battery stats.</p>
          * @param requiresDeviceIdle Whether or not the device need be within an idle maintenance
          *                           window.
@@ -339,17 +339,17 @@
         }
 
         /**
-         * Specify that this task should recur with the provided interval, not more than once per
-         * period. You have no control over when within this interval this task will be executed,
+         * Specify that this job should recur with the provided interval, not more than once per
+         * period. You have no control over when within this interval this job will be executed,
          * only the guarantee that it will be executed at most once within this interval.
-         * A periodic task will be repeated until the phone is turned off, however it will only be
+         * A periodic job will be repeated until the phone is turned off, however it will only be
          * persisted beyond boot if the client app has declared the
          * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission. You can schedule
-         * periodic tasks without this permission, they simply will cease to exist after the phone
+         * periodic jobs without this permission, they simply will cease to exist after the phone
          * restarts.
          * Setting this function on the builder with {@link #setMinimumLatency(long)} or
          * {@link #setOverrideDeadline(long)} will result in an error.
-         * @param intervalMillis Millisecond interval for which this task will repeat.
+         * @param intervalMillis Millisecond interval for which this job will repeat.
          */
         public Builder setPeriodic(long intervalMillis) {
             mIsPeriodic = true;
@@ -359,11 +359,11 @@
         }
 
         /**
-         * Specify that this task should be delayed by the provided amount of time.
-         * Because it doesn't make sense setting this property on a periodic task, doing so will
+         * Specify that this job should be delayed by the provided amount of time.
+         * Because it doesn't make sense setting this property on a periodic job, doing so will
          * throw an {@link java.lang.IllegalArgumentException} when
-         * {@link android.app.task.Task.Builder#build()} is called.
-         * @param minLatencyMillis Milliseconds before which this task will not be considered for
+         * {@link android.app.job.JobInfo.Builder#build()} is called.
+         * @param minLatencyMillis Milliseconds before which this job will not be considered for
          *                         execution.
          */
         public Builder setMinimumLatency(long minLatencyMillis) {
@@ -373,11 +373,11 @@
         }
 
         /**
-         * Set deadline which is the maximum scheduling latency. The task will be run by this
+         * Set deadline which is the maximum scheduling latency. The job will be run by this
          * deadline even if other requirements are not met. Because it doesn't make sense setting
-         * this property on a periodic task, doing so will throw an
+         * this property on a periodic job, doing so will throw an
          * {@link java.lang.IllegalArgumentException} when
-         * {@link android.app.task.Task.Builder#build()} is called.
+         * {@link android.app.job.JobInfo.Builder#build()} is called.
          */
         public Builder setOverrideDeadline(long maxExecutionDelayMillis) {
             mMaxExecutionDelayMillis = maxExecutionDelayMillis;
@@ -389,13 +389,13 @@
          * Set up the back-off/retry policy.
          * This defaults to some respectable values: {5 seconds, Exponential}. We cap back-off at
          * 1hr.
-         * Note that trying to set a backoff criteria for a task with
+         * Note that trying to set a backoff criteria for a job with
          * {@link #setRequiresDeviceIdle(boolean)} will throw an exception when you call build().
-         * This is because back-off typically does not make sense for these types of tasks. See
-         * {@link android.app.task.TaskService#taskFinished(android.app.task.TaskParams, boolean)}
-         * for more description of the return value for the case of a task executing while in idle
+         * This is because back-off typically does not make sense for these types of jobs. See
+         * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
+         * for more description of the return value for the case of a job executing while in idle
          * mode.
-         * @param initialBackoffMillis Millisecond time interval to wait initially when task has
+         * @param initialBackoffMillis Millisecond time interval to wait initially when job has
          *                             failed.
          * @param backoffPolicy is one of {@link BackoffPolicy}
          */
@@ -407,25 +407,25 @@
         }
 
         /**
-         * @return The task object to hand to the TaskManager. This object is immutable.
+         * @return The job object to hand to the JobScheduler. This object is immutable.
          */
-        public Task build() {
+        public JobInfo build() {
             mExtras = new PersistableBundle(mExtras);  // Make our own copy.
-            // Check that a deadline was not set on a periodic task.
+            // Check that a deadline was not set on a periodic job.
             if (mIsPeriodic && (mMaxExecutionDelayMillis != 0L)) {
                 throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +
-                        "periodic task.");
+                        "periodic job.");
             }
             if (mIsPeriodic && (mMinLatencyMillis != 0L)) {
                 throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
-                        "periodic task");
+                        "periodic job");
             }
             if (mBackoffPolicySet && mRequiresDeviceIdle) {
-                throw new IllegalArgumentException("An idle mode task will not respect any" +
+                throw new IllegalArgumentException("An idle mode job will not respect any" +
                         " back-off policy, so calling setBackoffCriteria with" +
                         " setRequiresDeviceIdle is an error.");
             }
-            return new Task(this);
+            return new JobInfo(this);
         }
     }
 
diff --git a/core/java/android/app/task/TaskParams.aidl b/core/java/android/app/job/JobParameters.aidl
similarity index 91%
rename from core/java/android/app/task/TaskParams.aidl
rename to core/java/android/app/job/JobParameters.aidl
index 9b25855..e7551b9 100644
--- a/core/java/android/app/task/TaskParams.aidl
+++ b/core/java/android/app/job/JobParameters.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.app.job;
 
-parcelable TaskParams;
\ No newline at end of file
+parcelable JobParameters;
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
new file mode 100644
index 0000000..724856a
--- /dev/null
+++ b/core/java/android/app/job/JobParameters.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.job;
+
+import android.app.job.IJobCallback;
+import android.app.job.IJobCallback.Stub;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+
+/**
+ * Contains the parameters used to configure/identify your job. You do not create this object
+ * yourself, instead it is handed in to your application by the System.
+ */
+public class JobParameters implements Parcelable {
+
+    private final int jobId;
+    private final PersistableBundle extras;
+    private final IBinder callback;
+
+    /** @hide */
+    public JobParameters(int jobId, PersistableBundle extras, IBinder callback) {
+        this.jobId = jobId;
+        this.extras = extras;
+        this.callback = callback;
+    }
+
+    /**
+     * @return The unique id of this job, specified at creation time.
+     */
+    public int getJobId() {
+        return jobId;
+    }
+
+    /**
+     * @return The extras you passed in when constructing this job with
+     * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will
+     * never be null. If you did not set any extras this will be an empty bundle.
+     */
+    public PersistableBundle getExtras() {
+        return extras;
+    }
+
+    /** @hide */
+    public IJobCallback getCallback() {
+        return IJobCallback.Stub.asInterface(callback);
+    }
+
+    private JobParameters(Parcel in) {
+        jobId = in.readInt();
+        extras = in.readPersistableBundle();
+        callback = in.readStrongBinder();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(jobId);
+        dest.writePersistableBundle(extras);
+        dest.writeStrongBinder(callback);
+    }
+
+    public static final Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
+        @Override
+        public JobParameters createFromParcel(Parcel in) {
+            return new JobParameters(in);
+        }
+
+        @Override
+        public JobParameters[] newArray(int size) {
+            return new JobParameters[size];
+        }
+    };
+}
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
new file mode 100644
index 0000000..7fe192c
--- /dev/null
+++ b/core/java/android/app/job/JobScheduler.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.job;
+
+import java.util.List;
+
+import android.content.Context;
+
+/**
+ * Class for scheduling various types of jobs with the scheduling framework on the device.
+ *
+ * <p>You do not
+ * instantiate this class directly; instead, retrieve it through
+ * {@link android.content.Context#getSystemService
+ * Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}.
+ */
+public abstract class JobScheduler {
+    /**
+     * Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur
+     * if the run-time for your job is too short, or perhaps the system can't resolve the
+     * requisite {@link JobService} in your package.
+     */
+    public static final int RESULT_FAILURE = 0;
+    /**
+     * Returned from {@link #schedule(JobInfo)} if this application has made too many requests for
+     * work over too short a time.
+     */
+    // TODO: Determine if this is necessary.
+    public static final int RESULT_SUCCESS = 1;
+
+    /**
+     * @param job The job you wish scheduled. See
+     * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
+     * you can schedule.
+     * @return If >0, this int returns the jobId of the successfully scheduled job.
+     * Otherwise you have to compare the return value to the error codes defined in this class.
+     */
+    public abstract int schedule(JobInfo job);
+
+    /**
+     * Cancel a job that is pending in the JobScheduler.
+     * @param jobId unique identifier for this job. Obtain this value from the jobs returned by
+     * {@link #getAllPendingJobs()}.
+     * @return
+     */
+    public abstract void cancel(int jobId);
+
+    /**
+     * Cancel all jobs that have been registered with the JobScheduler by this package.
+     */
+    public abstract void cancelAll();
+
+    /**
+     * @return a list of all the jobs registered by this package that have not yet been executed.
+     */
+    public abstract List<JobInfo> getAllPendingJobs();
+
+}
diff --git a/core/java/android/app/job/JobService.java b/core/java/android/app/job/JobService.java
new file mode 100644
index 0000000..eea0268
--- /dev/null
+++ b/core/java/android/app/job/JobService.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.job;
+
+import android.app.Service;
+import android.app.job.IJobCallback;
+import android.app.job.IJobService;
+import android.app.job.IJobService.Stub;
+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 com.android.internal.annotations.GuardedBy;
+
+/**
+ * <p>Entry point for the callback from the {@link android.app.job.JobScheduler}.</p>
+ * <p>This is the base class that handles asynchronous requests that were previously scheduled. You
+ * are responsible for overriding {@link JobService#onStartJob(JobParameters)}, which is where
+ * you will implement your job logic.</p>
+ * <p>This service executes each incoming job on a {@link android.os.Handler} running on your
+ * application's main thread. This means that you <b>must</b> offload your execution logic to
+ * another thread/handler/{@link android.os.AsyncTask} of your choosing. Not doing so will result
+ * in blocking any future callbacks from the JobManager - specifically
+ * {@link #onStopJob(android.app.job.JobParameters)}, which is meant to inform you that the
+ * scheduling requirements are no longer being met.</p>
+ */
+public abstract class JobService extends Service {
+    private static final String TAG = "JobService";
+
+    /**
+     * Job services must be protected with this permission:
+     *
+     * <pre class="prettyprint">
+     *     <service android:name="MyJobService"
+     *              android:permission="android.permission.BIND_JOB_SERVICE" >
+     *         ...
+     *     </service>
+     * </pre>
+     *
+     * <p>If a job 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_JOB_SERVICE";
+
+    /**
+     * Identifier for a message that will result in a call to
+     * {@link #onStartJob(android.app.job.JobParameters)}.
+     */
+    private final int MSG_EXECUTE_JOB = 0;
+    /**
+     * Message that will result in a call to {@link #onStopJob(android.app.job.JobParameters)}.
+     */
+    private final int MSG_STOP_JOB = 1;
+    /**
+     * Message that the client has completed execution of this job.
+     */
+    private final int MSG_JOB_FINISHED = 2;
+
+    /** Lock object for {@link #mHandler}. */
+    private final Object mHandlerLock = new Object();
+
+    /**
+     * Handler we post jobs to. Responsible for calling into the client logic, and handling the
+     * callback to the system.
+     */
+    @GuardedBy("mHandlerLock")
+    JobHandler mHandler;
+
+    /** Binder for this service. */
+    IJobService mBinder = new IJobService.Stub() {
+        @Override
+        public void startJob(JobParameters jobParams) {
+            ensureHandler();
+            Message m = Message.obtain(mHandler, MSG_EXECUTE_JOB, jobParams);
+            m.sendToTarget();
+        }
+        @Override
+        public void stopJob(JobParameters jobParams) {
+            ensureHandler();
+            Message m = Message.obtain(mHandler, MSG_STOP_JOB, jobParams);
+            m.sendToTarget();
+        }
+    };
+
+    /** @hide */
+    void ensureHandler() {
+        synchronized (mHandlerLock) {
+            if (mHandler == null) {
+                mHandler = new JobHandler(getMainLooper());
+            }
+        }
+    }
+
+    /**
+     * Runs on application's main thread - callbacks are meant to offboard work to some other
+     * (app-specified) mechanism.
+     * @hide
+     */
+    class JobHandler extends Handler {
+        JobHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final JobParameters params = (JobParameters) msg.obj;
+            switch (msg.what) {
+                case MSG_EXECUTE_JOB:
+                    try {
+                        boolean workOngoing = JobService.this.onStartJob(params);
+                        ackStartMessage(params, workOngoing);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Error while executing job: " + params.getJobId());
+                        throw new RuntimeException(e);
+                    }
+                    break;
+                case MSG_STOP_JOB:
+                    try {
+                        boolean ret = JobService.this.onStopJob(params);
+                        ackStopMessage(params, ret);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Application unable to handle onStopJob.", e);
+                        throw new RuntimeException(e);
+                    }
+                    break;
+                case MSG_JOB_FINISHED:
+                    final boolean needsReschedule = (msg.arg2 == 1);
+                    IJobCallback callback = params.getCallback();
+                    if (callback != null) {
+                        try {
+                            callback.jobFinished(params.getJobId(), needsReschedule);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Error reporting job finish to system: binder has gone" +
+                                    "away.");
+                        }
+                    } else {
+                        Log.e(TAG, "finishJob() called for a nonexistent job id.");
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Unrecognised message received.");
+                    break;
+            }
+        }
+
+        private void ackStartMessage(JobParameters params, boolean workOngoing) {
+            final IJobCallback callback = params.getCallback();
+            final int jobId = params.getJobId();
+            if (callback != null) {
+                try {
+                     callback.acknowledgeStartMessage(jobId, workOngoing);
+                } catch(RemoteException e) {
+                    Log.e(TAG, "System unreachable for starting job.");
+                }
+            } else {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Attempting to ack a job that has already been processed.");
+                }
+            }
+        }
+
+        private void ackStopMessage(JobParameters params, boolean reschedule) {
+            final IJobCallback callback = params.getCallback();
+            final int jobId = params.getJobId();
+            if (callback != null) {
+                try {
+                    callback.acknowledgeStopMessage(jobId, reschedule);
+                } catch(RemoteException e) {
+                    Log.e(TAG, "System unreachable for stopping job.");
+                }
+            } else {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Attempting to ack a job that has already been processed.");
+                }
+            }
+        }
+    }
+
+    /** @hide */
+    public final IBinder onBind(Intent intent) {
+        return mBinder.asBinder();
+    }
+
+    /**
+     * Override this method with the callback logic for your job. Any such logic needs to be
+     * performed on a separate thread, as this function is executed on your application's main
+     * thread.
+     *
+     * @param params Parameters specifying info about this job, including the extras bundle you
+     *               optionally provided at job-creation time.
+     * @return True if your service needs to process the work (on a separate thread). False if
+     * there's no more work to be done for this job.
+     */
+    public abstract boolean onStartJob(JobParameters params);
+
+    /**
+     * This method is called if the system has determined that you must stop execution of your job
+     * even before you've had a chance to call {@link #jobFinished(JobParameters, boolean)}.
+     *
+     * <p>This will happen if the requirements specified at schedule time are no longer met. For
+     * example you may have requested WiFi with
+     * {@link android.app.job.JobInfo.Builder#setRequiredNetworkCapabilities(int)}, yet while your
+     * job was executing the user toggled WiFi. Another example is if you had specified
+     * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
+     * idle maintenance window. You are solely responsible for the behaviour of your application
+     * upon receipt of this message; your app will likely start to misbehave if you ignore it. One
+     * immediate repercussion is that the system will cease holding a wakelock for you.</p>
+     *
+     * @param params Parameters specifying info about this job.
+     * @return True to indicate to the JobManager whether you'd like to reschedule this job based
+     * on the retry criteria provided at job creation-time. False to drop the job. Regardless of
+     * the value returned, your job must stop executing.
+     */
+    public abstract boolean onStopJob(JobParameters params);
+
+    /**
+     * Callback to inform the JobManager you've finished executing. This can be called from any
+     * thread, as it will ultimately be run on your application's main thread. When the system
+     * receives this message it will release the wakelock being held.
+     * <p>
+     *     You can specify post-execution behaviour to the scheduler here with
+     *     <code>needsReschedule </code>. This will apply a back-off timer to your job based on
+     *     the default, or what was set with
+     *     {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}. The original
+     *     requirements are always honoured even for a backed-off job. Note that a job running in
+     *     idle mode will not be backed-off. Instead what will happen is the job will be re-added
+     *     to the queue and re-executed within a future idle maintenance window.
+     * </p>
+     *
+     * @param params Parameters specifying system-provided info about this job, this was given to
+     *               your application in {@link #onStartJob(JobParameters)}.
+     * @param needsReschedule True if this job is complete, false if you want the JobManager to
+     *                        reschedule you.
+     */
+    public final void jobFinished(JobParameters params, boolean needsReschedule) {
+        ensureHandler();
+        Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params);
+        m.arg2 = needsReschedule ? 1 : 0;
+        m.sendToTarget();
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/app/maintenance/package.html b/core/java/android/app/maintenance/package.html
new file mode 100644
index 0000000..1c9bf9d
--- /dev/null
+++ b/core/java/android/app/maintenance/package.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+    {@hide}
+</body>
+</html>
diff --git a/core/java/android/app/task/ITaskCallback.aidl b/core/java/android/app/task/ITaskCallback.aidl
deleted file mode 100644
index d8a32fd..0000000
--- a/core/java/android/app/task/ITaskCallback.aidl
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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.task;
-
-import android.app.task.ITaskService;
-import android.app.task.TaskParams;
-
-/**
- * The server side of the TaskManager 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 Task Service instance is reporting.
- *
- * {@hide}
- */
-interface ITaskCallback {
-    /**
-     * Immediate callback to the system after sending a start signal, used to quickly detect ANR.
-     *
-     * @param taskId Unique integer used to identify this task.
-     * @param ongoing True to indicate that the client is processing the task. False if the task is
-     * complete
-     */
-    void acknowledgeStartMessage(int taskId, boolean ongoing);
-    /**
-     * Immediate callback to the system after sending a stop signal, used to quickly detect ANR.
-     *
-     * @param taskId Unique integer used to identify this task.
-     * @param rescheulde Whether or not to reschedule this task.
-     */
-    void acknowledgeStopMessage(int taskId, boolean reschedule);
-    /*
-     * Tell the task manager that the client is done with its execution, so that it can go on to
-     * the next one and stop attributing wakelock time to us etc.
-     *
-     * @param taskId Unique integer used to identify this task.
-     * @param reschedule Whether or not to reschedule this task.
-     */
-    void taskFinished(int taskId, boolean reschedule);
-}
diff --git a/core/java/android/app/task/TaskManager.java b/core/java/android/app/task/TaskManager.java
deleted file mode 100644
index 00f57da..0000000
--- a/core/java/android/app/task/TaskManager.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.task;
-
-import java.util.List;
-
-import android.content.Context;
-
-/**
- * Class for scheduling various types of tasks with the scheduling framework on the device.
- *
- * <p>You do not
- * instantiate this class directly; instead, retrieve it through
- * {@link android.content.Context#getSystemService
- * Context.getSystemService(Context.TASK_SERVICE)}.
- */
-public abstract class TaskManager {
-    /*
-     * Returned from {@link #schedule(Task)} when an invalid parameter was supplied. This can occur
-     * if the run-time for your task is too short, or perhaps the system can't resolve the
-     * requisite {@link TaskService} in your package.
-     */
-    public static final int RESULT_FAILURE = 0;
-    /**
-     * Returned from {@link #schedule(Task)} if this application has made too many requests for
-     * work over too short a time.
-     */
-    // TODO: Determine if this is necessary.
-    public static final int RESULT_SUCCESS = 1;
-
-    /**
-     * @param task The task you wish scheduled. See
-     * {@link android.app.task.Task.Builder Task.Builder} for more detail on the sorts of tasks
-     * you can schedule.
-     * @return If >0, this int returns the taskId of the successfully scheduled task.
-     * Otherwise you have to compare the return value to the error codes defined in this class.
-     */
-    public abstract int schedule(Task task);
-
-    /**
-     * Cancel a task that is pending in the TaskManager.
-     * @param taskId unique identifier for this task. Obtain this value from the tasks returned by
-     * {@link #getAllPendingTasks()}.
-     * @return
-     */
-    public abstract void cancel(int taskId);
-
-    /**
-     * Cancel all tasks that have been registered with the TaskManager by this package.
-     */
-    public abstract void cancelAll();
-
-    /**
-     * @return a list of all the tasks registered by this package that have not yet been executed.
-     */
-    public abstract List<Task> getAllPendingTasks();
-
-}
diff --git a/core/java/android/app/task/TaskParams.java b/core/java/android/app/task/TaskParams.java
deleted file mode 100644
index f4908c6..0000000
--- a/core/java/android/app/task/TaskParams.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.task;
-
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-
-/**
- * Contains the parameters used to configure/identify your task. You do not create this object
- * yourself, instead it is handed in to your application by the System.
- */
-public class TaskParams implements Parcelable {
-
-    private final int taskId;
-    private final PersistableBundle extras;
-    private final IBinder callback;
-
-    /** @hide */
-    public TaskParams(int taskId, PersistableBundle extras, IBinder callback) {
-        this.taskId = taskId;
-        this.extras = extras;
-        this.callback = callback;
-    }
-
-    /**
-     * @return The unique id of this task, specified at creation time.
-     */
-    public int getTaskId() {
-        return taskId;
-    }
-
-    /**
-     * @return The extras you passed in when constructing this task with
-     * {@link android.app.task.Task.Builder#setExtras(android.os.PersistableBundle)}. This will
-     * never be null. If you did not set any extras this will be an empty bundle.
-     */
-    public PersistableBundle getExtras() {
-        return extras;
-    }
-
-    /** @hide */
-    public ITaskCallback getCallback() {
-        return ITaskCallback.Stub.asInterface(callback);
-    }
-
-    private TaskParams(Parcel in) {
-        taskId = in.readInt();
-        extras = in.readPersistableBundle();
-        callback = in.readStrongBinder();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(taskId);
-        dest.writePersistableBundle(extras);
-        dest.writeStrongBinder(callback);
-    }
-
-    public static final Creator<TaskParams> CREATOR = new Creator<TaskParams>() {
-        @Override
-        public TaskParams createFromParcel(Parcel in) {
-            return new TaskParams(in);
-        }
-
-        @Override
-        public TaskParams[] newArray(int size) {
-            return new TaskParams[size];
-        }
-    };
-}
diff --git a/core/java/android/app/task/TaskService.java b/core/java/android/app/task/TaskService.java
deleted file mode 100644
index 8ce4484..0000000
--- a/core/java/android/app/task/TaskService.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.task;
-
-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 com.android.internal.annotations.GuardedBy;
-
-/**
- * <p>Entry point for the callback from the {@link android.app.task.TaskManager}.</p>
- * <p>This is the base class that handles asynchronous requests that were previously scheduled. You
- * are responsible for overriding {@link TaskService#onStartTask(TaskParams)}, which is where
- * you will implement your task logic.</p>
- * <p>This service executes each incoming task on a {@link android.os.Handler} running on your
- * application's main thread. This means that you <b>must</b> offload your execution logic to
- * another thread/handler/{@link android.os.AsyncTask} of your choosing. Not doing so will result
- * in blocking any future callbacks from the TaskManager - specifically
- * {@link #onStopTask(android.app.task.TaskParams)}, which is meant to inform you that the
- * scheduling requirements are no longer being met.</p>
- */
-public abstract class TaskService extends Service {
-    private static final String TAG = "TaskService";
-
-    /**
-     * Task services must be protected with this permission:
-     *
-     * <pre class="prettyprint">
-     *     <service android:name="MyTaskService"
-     *              android:permission="android.permission.BIND_TASK_SERVICE" >
-     *         ...
-     *     </service>
-     * </pre>
-     *
-     * <p>If a task 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_TASK_SERVICE";
-
-    /**
-     * Identifier for a message that will result in a call to
-     * {@link #onStartTask(android.app.task.TaskParams)}.
-     */
-    private final int MSG_EXECUTE_TASK = 0;
-    /**
-     * Message that will result in a call to {@link #onStopTask(android.app.task.TaskParams)}.
-     */
-    private final int MSG_STOP_TASK = 1;
-    /**
-     * Message that the client has completed execution of this task.
-     */
-    private final int MSG_TASK_FINISHED = 2;
-
-    /** Lock object for {@link #mHandler}. */
-    private final Object mHandlerLock = new Object();
-
-    /**
-     * Handler we post tasks to. Responsible for calling into the client logic, and handling the
-     * callback to the system.
-     */
-    @GuardedBy("mHandlerLock")
-    TaskHandler mHandler;
-
-    /** Binder for this service. */
-    ITaskService mBinder = new ITaskService.Stub() {
-        @Override
-        public void startTask(TaskParams taskParams) {
-            ensureHandler();
-            Message m = Message.obtain(mHandler, MSG_EXECUTE_TASK, taskParams);
-            m.sendToTarget();
-        }
-        @Override
-        public void stopTask(TaskParams taskParams) {
-            ensureHandler();
-            Message m = Message.obtain(mHandler, MSG_STOP_TASK, taskParams);
-            m.sendToTarget();
-        }
-    };
-
-    /** @hide */
-    void ensureHandler() {
-        synchronized (mHandlerLock) {
-            if (mHandler == null) {
-                mHandler = new TaskHandler(getMainLooper());
-            }
-        }
-    }
-
-    /**
-     * Runs on application's main thread - callbacks are meant to offboard work to some other
-     * (app-specified) mechanism.
-     * @hide
-     */
-    class TaskHandler extends Handler {
-        TaskHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            final TaskParams params = (TaskParams) msg.obj;
-            switch (msg.what) {
-                case MSG_EXECUTE_TASK:
-                    try {
-                        boolean workOngoing = TaskService.this.onStartTask(params);
-                        ackStartMessage(params, workOngoing);
-                    } catch (Exception e) {
-                        Log.e(TAG, "Error while executing task: " + params.getTaskId());
-                        throw new RuntimeException(e);
-                    }
-                    break;
-                case MSG_STOP_TASK:
-                    try {
-                        boolean ret = TaskService.this.onStopTask(params);
-                        ackStopMessage(params, ret);
-                    } catch (Exception e) {
-                        Log.e(TAG, "Application unable to handle onStopTask.", e);
-                        throw new RuntimeException(e);
-                    }
-                    break;
-                case MSG_TASK_FINISHED:
-                    final boolean needsReschedule = (msg.arg2 == 1);
-                    ITaskCallback callback = params.getCallback();
-                    if (callback != null) {
-                        try {
-                            callback.taskFinished(params.getTaskId(), needsReschedule);
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Error reporting task finish to system: binder has gone" +
-                                    "away.");
-                        }
-                    } else {
-                        Log.e(TAG, "finishTask() called for a nonexistent task id.");
-                    }
-                    break;
-                default:
-                    Log.e(TAG, "Unrecognised message received.");
-                    break;
-            }
-        }
-
-        private void ackStartMessage(TaskParams params, boolean workOngoing) {
-            final ITaskCallback callback = params.getCallback();
-            final int taskId = params.getTaskId();
-            if (callback != null) {
-                try {
-                     callback.acknowledgeStartMessage(taskId, workOngoing);
-                } catch(RemoteException e) {
-                    Log.e(TAG, "System unreachable for starting task.");
-                }
-            } else {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "Attempting to ack a task that has already been processed.");
-                }
-            }
-        }
-
-        private void ackStopMessage(TaskParams params, boolean reschedule) {
-            final ITaskCallback callback = params.getCallback();
-            final int taskId = params.getTaskId();
-            if (callback != null) {
-                try {
-                    callback.acknowledgeStopMessage(taskId, reschedule);
-                } catch(RemoteException e) {
-                    Log.e(TAG, "System unreachable for stopping task.");
-                }
-            } else {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "Attempting to ack a task that has already been processed.");
-                }
-            }
-        }
-    }
-
-    /** @hide */
-    public final IBinder onBind(Intent intent) {
-        return mBinder.asBinder();
-    }
-
-    /**
-     * Override this method with the callback logic for your task. Any such logic needs to be
-     * performed on a separate thread, as this function is executed on your application's main
-     * thread.
-     *
-     * @param params Parameters specifying info about this task, including the extras bundle you
-     *               optionally provided at task-creation time.
-     * @return True if your service needs to process the work (on a separate thread). False if
-     * there's no more work to be done for this task.
-     */
-    public abstract boolean onStartTask(TaskParams params);
-
-    /**
-     * This method is called if the system has determined that you must stop execution of your task
-     * even before you've had a chance to call {@link #taskFinished(TaskParams, boolean)}.
-     *
-     * <p>This will happen if the requirements specified at schedule time are no longer met. For
-     * example you may have requested WiFi with
-     * {@link android.app.task.Task.Builder#setRequiredNetworkCapabilities(int)}, yet while your
-     * task was executing the user toggled WiFi. Another example is if you had specified
-     * {@link android.app.task.Task.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
-     * idle maintenance window. You are solely responsible for the behaviour of your application
-     * upon receipt of this message; your app will likely start to misbehave if you ignore it. One
-     * immediate repercussion is that the system will cease holding a wakelock for you.</p>
-     *
-     * @param params Parameters specifying info about this task.
-     * @return True to indicate to the TaskManager whether you'd like to reschedule this task based
-     * on the retry criteria provided at task creation-time. False to drop the task. Regardless of
-     * the value returned, your task must stop executing.
-     */
-    public abstract boolean onStopTask(TaskParams params);
-
-    /**
-     * Callback to inform the TaskManager you've finished executing. This can be called from any
-     * thread, as it will ultimately be run on your application's main thread. When the system
-     * receives this message it will release the wakelock being held.
-     * <p>
-     *     You can specify post-execution behaviour to the scheduler here with
-     *     <code>needsReschedule </code>. This will apply a back-off timer to your task based on
-     *     the default, or what was set with
-     *     {@link android.app.task.Task.Builder#setBackoffCriteria(long, int)}. The original
-     *     requirements are always honoured even for a backed-off task. Note that a task running in
-     *     idle mode will not be backed-off. Instead what will happen is the task will be re-added
-     *     to the queue and re-executed within a future idle maintenance window.
-     * </p>
-     *
-     * @param params Parameters specifying system-provided info about this task, this was given to
-     *               your application in {@link #onStartTask(TaskParams)}.
-     * @param needsReschedule True if this task is complete, false if you want the TaskManager to
-     *                        reschedule you.
-     */
-    public final void taskFinished(TaskParams params, boolean needsReschedule) {
-        ensureHandler();
-        Message m = Message.obtain(mHandler, MSG_TASK_FINISHED, params);
-        m.arg2 = needsReschedule ? 1 : 0;
-        m.sendToTarget();
-    }
-}
\ No newline at end of file
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9fe9bce..cdcfd2e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2059,7 +2059,7 @@
             PRINT_SERVICE,
             MEDIA_SESSION_SERVICE,
             BATTERY_SERVICE,
-            TASK_SERVICE,
+            JOB_SCHEDULER_SERVICE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceName {}
@@ -2116,8 +2116,8 @@
      * <dd> A {@link android.app.DownloadManager} for requesting HTTP downloads
      * <dt> {@link #BATTERY_SERVICE} ("batterymanager")
      * <dd> A {@link android.os.BatteryManager} for managing battery state
-     * <dt> {@link #TASK_SERVICE} ("taskmanager")
-     * <dd>  A {@link android.app.task.TaskManager} for managing scheduled tasks
+     * <dt> {@link #JOB_SCHEDULER_SERVICE} ("taskmanager")
+     * <dd>  A {@link android.app.job.JobScheduler} for managing scheduled tasks
      * </dl>
      *
      * <p>Note:  System services obtained via this API may be closely associated with
@@ -2171,8 +2171,8 @@
      * @see android.app.DownloadManager
      * @see #BATTERY_SERVICE
      * @see android.os.BatteryManager
-     * @see #TASK_SERVICE
-     * @see android.app.task.TaskManager
+     * @see #JOB_SCHEDULER_SERVICE
+     * @see android.app.job.JobScheduler
      */
     public abstract Object getSystemService(@ServiceName @NonNull String name);
 
@@ -2761,12 +2761,12 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
-     * android.app.task.TaskManager} instance for managing occasional
+     * android.app.job.JobScheduler} instance for managing occasional
      * background tasks.
      * @see #getSystemService
-     * @see android.app.task.TaskManager
+     * @see android.app.job.JobScheduler
      */
-    public static final String TASK_SERVICE = "task";
+    public static final String JOB_SCHEDULER_SERVICE = "jobscheduler";
 
     /**
      * Determine whether the given permission is allowed for a particular
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 04c0b9f..69fa408 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -67,7 +67,6 @@
          *
          * @param user The UserHandle of the profile that generated the change.
          * @param packageName The name of the package that was removed.
-         * @hide remove before ship
          */
         void onPackageRemoved(UserHandle user, String packageName);
 
@@ -76,7 +75,6 @@
          *
          * @param user The UserHandle of the profile that generated the change.
          * @param packageName The name of the package that was added.
-         * @hide remove before ship
          */
         void onPackageAdded(UserHandle user, String packageName);
 
@@ -85,7 +83,6 @@
          *
          * @param user The UserHandle of the profile that generated the change.
          * @param packageName The name of the package that has changed.
-         * @hide remove before ship
          */
         void onPackageChanged(UserHandle user, String packageName);
 
@@ -99,7 +96,6 @@
          *            available.
          * @param replacing Indicates whether these packages are replacing
          *            existing ones.
-         * @hide remove before ship
          */
         void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing);
 
@@ -113,59 +109,9 @@
          *            unavailable.
          * @param replacing Indicates whether the packages are about to be
          *            replaced with new versions.
-         * @hide remove before ship
          */
         void onPackagesUnavailable(UserHandle user, String[] packageNames, boolean replacing);
 
-        /**
-         * Indicates that a package was removed from the specified profile.
-         *
-         * @param packageName The name of the package that was removed.
-         * @param user The UserHandle of the profile that generated the change.
-         */
-        void onPackageRemoved(String packageName, UserHandle user);
-
-        /**
-         * Indicates that a package was added to the specified profile.
-         *
-         * @param packageName The name of the package that was added.
-         * @param user The UserHandle of the profile that generated the change.
-         */
-        void onPackageAdded(String packageName, UserHandle user);
-
-        /**
-         * Indicates that a package was modified in the specified profile.
-         *
-         * @param packageName The name of the package that has changed.
-         * @param user The UserHandle of the profile that generated the change.
-         */
-        void onPackageChanged(String packageName, UserHandle user);
-
-        /**
-         * Indicates that one or more packages have become available. For
-         * example, this can happen when a removable storage card has
-         * reappeared.
-         *
-         * @param packageNames The names of the packages that have become
-         *            available.
-         * @param user The UserHandle of the profile that generated the change.
-         * @param replacing Indicates whether these packages are replacing
-         *            existing ones.
-         */
-        void onPackagesAvailable(String [] packageNames, UserHandle user, boolean replacing);
-
-        /**
-         * Indicates that one or more packages have become unavailable. For
-         * example, this can happen when a removable storage card has been
-         * removed.
-         *
-         * @param packageNames The names of the packages that have become
-         *            unavailable.
-         * @param user The UserHandle of the profile that generated the change.
-         * @param replacing Indicates whether the packages are about to be
-         *            replaced with new versions.
-         */
-        void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing);
     }
 
     /** @hide */
@@ -361,8 +307,7 @@
             }
             synchronized (LauncherApps.this) {
                 for (OnAppsChangedListener listener : mListeners) {
-                    listener.onPackageRemoved(user, packageName); // TODO: Remove before ship
-                    listener.onPackageRemoved(packageName, user);
+                    listener.onPackageRemoved(user, packageName);
                 }
             }
         }
@@ -374,8 +319,7 @@
             }
             synchronized (LauncherApps.this) {
                 for (OnAppsChangedListener listener : mListeners) {
-                    listener.onPackageChanged(user, packageName); // TODO: Remove before ship
-                    listener.onPackageChanged(packageName, user);
+                    listener.onPackageChanged(user, packageName);
                 }
             }
         }
@@ -387,8 +331,7 @@
             }
             synchronized (LauncherApps.this) {
                 for (OnAppsChangedListener listener : mListeners) {
-                    listener.onPackageAdded(user, packageName); // TODO: Remove before ship
-                    listener.onPackageAdded(packageName, user);
+                    listener.onPackageAdded(user, packageName);
                 }
             }
         }
@@ -401,8 +344,7 @@
             }
             synchronized (LauncherApps.this) {
                 for (OnAppsChangedListener listener : mListeners) {
-                    listener.onPackagesAvailable(user, packageNames, replacing); // TODO: Remove
-                    listener.onPackagesAvailable(packageNames, user, replacing);
+                    listener.onPackagesAvailable(user, packageNames, replacing);
                 }
             }
         }
@@ -415,8 +357,7 @@
             }
             synchronized (LauncherApps.this) {
                 for (OnAppsChangedListener listener : mListeners) {
-                    listener.onPackagesUnavailable(user, packageNames, replacing); // TODO: Remove
-                    listener.onPackagesUnavailable(packageNames, user, replacing);
+                    listener.onPackagesUnavailable(user, packageNames, replacing);
                 }
             }
         }
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 5fd0f9b..d98bdc2 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -29,19 +29,19 @@
  *
  * <p>Creating a session is an expensive operation and can take several hundred milliseconds, since
  * it requires configuring the camera device's internal pipelines and allocating memory buffers for
- * sending images to the desired targets. While
- * {@link CameraDevice#createCaptureSession createCaptureSession} will provide a
- * CameraCaptureSession object immediately, configuration won't be complete until the
- * {@link CameraCaptureSession.StateListener#onConfigured onConfigured} callback is called for the
- * first time. If configuration cannot be completed, then the
+ * sending images to the desired targets. Therefore the setup is done asynchronously, and
+ * {@link CameraDevice#createCaptureSession createCaptureSession} will send the ready-to-use
+ * CameraCaptureSession to the provided listener's
+ * {@link CameraCaptureSession.StateListener#onConfigured onConfigured} callback. If configuration
+ * cannot be completed, then the
  * {@link CameraCaptureSession.StateListener#onConfigureFailed onConfigureFailed} is called, and the
  * session will not become active.</p>
- *
+ *<!--
  * <p>Any capture requests (repeating or non-repeating) submitted before the session is ready will
  * be queued up and will begin capture once the session becomes ready. In case the session cannot be
  * configured and {@link StateListener#onConfigureFailed onConfigureFailed} is called, all queued
  * capture requests are discarded.</p>
- *
+ *-->
  * <p>If a new session is created by the camera device, then the previous session is closed, and its
  * associated {@link StateListener#onClosed onClosed} callback will be invoked.  All
  * of the session methods will throw an IllegalStateException if called once the session is
@@ -166,10 +166,6 @@
      * capture request will be processed before any further repeating
      * requests are processed.<p>
      *
-     * <p>Repeating requests are a simple way for an application to maintain a
-     * preview or other continuous stream of frames, without having to submit
-     * requests through {@link #capture} at video rates.</p>
-     *
      * <p>To stop the repeating capture, call {@link #stopRepeating}. Calling
      * {@link #abortCaptures} will also clear the request.</p>
      *
@@ -323,7 +319,7 @@
      *
      * @see #setRepeatingRequest
      * @see #setRepeatingBurst
-     * @see #configureOutputs
+     * @see CameraDevice#createCaptureSession
      */
     public abstract void abortCaptures() throws CameraAccessException;
 
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 08cfc87..9eea545 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -30,7 +30,7 @@
  *
  * <p>These properties are fixed for a given CameraDevice, and can be queried
  * through the {@link CameraManager CameraManager}
- * interface in addition to through the CameraDevice interface.</p>
+ * interface with {@link CameraManager#getCameraCharacteristics}.</p>
  *
  * <p>{@link CameraCharacteristics} objects are immutable.</p>
  *
@@ -320,7 +320,7 @@
 
     /**
      * <p>List of frame rate ranges supported by the
-     * AE algorithm/hardware</p>
+     * auto-exposure (AE) algorithm/hardware</p>
      */
     public static final Key<android.util.Range<Integer>[]> CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES =
             new Key<android.util.Range<Integer>[]>("android.control.aeAvailableTargetFpsRanges", new TypeReference<android.util.Range<Integer>[]>() {{ }});
@@ -343,7 +343,7 @@
             new Key<Rational>("android.control.aeCompensationStep", Rational.class);
 
     /**
-     * <p>List of AF modes that can be
+     * <p>List of auto-focus (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
@@ -496,7 +496,7 @@
             new Key<int[]>("android.hotPixel.availableHotPixelModes", int[].class);
 
     /**
-     * <p>Supported resolutions for the JPEG thumbnail</p>
+     * <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).
@@ -555,7 +555,7 @@
      * <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
+     * <p>If OIS is not implemented for a given camera device, this will
      * contain only OFF.</p>
      *
      * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
@@ -612,7 +612,7 @@
 
     /**
      * <p>Direction the camera faces relative to
-     * device screen</p>
+     * device screen.</p>
      * @see #LENS_FACING_FRONT
      * @see #LENS_FACING_BACK
      */
@@ -622,7 +622,7 @@
     /**
      * <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>
+     * <p>Full-capability camera devices must always support OFF and FAST.</p>
      *
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      */
@@ -778,17 +778,20 @@
             new Key<Byte>("android.request.pipelineMaxDepth", byte.class);
 
     /**
-     * <p>Optional. Defaults to 1. Defines how many sub-components
+     * <p>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>
+     * <p>Optional; defaults to 1. A value of 1 means that partial
+     * results are not supported, and only the final TotalCaptureResult will
+     * be produced by the camera device.</p>
+     * <p>A typical use case for this might be: after requesting an
+     * auto-focus (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 application, 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);
@@ -805,8 +808,6 @@
      * 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>
@@ -814,14 +815,11 @@
      * <li>MANUAL_POST_PROCESSING</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>
+     * devices, but the application 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_MANUAL_POST_PROCESSING
-     * @see #REQUEST_AVAILABLE_CAPABILITIES_ZSL
      * @see #REQUEST_AVAILABLE_CAPABILITIES_DNG
      */
     public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES =
@@ -837,7 +835,6 @@
      * 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
@@ -862,7 +859,6 @@
      * 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 CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
@@ -878,7 +874,6 @@
      * 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 =
@@ -926,10 +921,15 @@
             new Key<android.util.Size[]>("android.scaler.availableJpegSizes", android.util.Size[].class);
 
     /**
-     * <p>The maximum ratio between active area width
-     * and crop region width, or between active area height and
-     * crop region height, if the crop region height is larger
-     * than width</p>
+     * <p>The maximum ratio between both active area width
+     * and crop region width, and active area height and
+     * crop region height.</p>
+     * <p>This represents the maximum amount of zooming possible by
+     * the camera device, or equivalently, the minimum cropping
+     * window size.</p>
+     * <p>Crop regions that have a width or height that is smaller
+     * than this ratio allows will be rounded up to the minimum
+     * allowed size by the camera device.</p>
      */
     public static final Key<Float> SCALER_AVAILABLE_MAX_DIGITAL_ZOOM =
             new Key<Float>("android.scaler.availableMaxDigitalZoom", float.class);
@@ -1326,15 +1326,21 @@
             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>
+     * <p>The minimum and maximum valid values for the
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} control.</p>
+     * <p>The values are the standard ISO sensitivity values,
+     * as defined in ISO 12232:2006.</p>
+     *
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      */
     public static final Key<android.util.Range<Integer>> SENSOR_INFO_SENSITIVITY_RANGE =
             new Key<android.util.Range<Integer>>("android.sensor.info.sensitivityRange", new TypeReference<android.util.Range<Integer>>() {{ }});
 
     /**
-     * <p>Arrangement of color filters on sensor;
+     * <p>The arrangement of color filters on sensor;
      * represents the colors in the top-left 2x2 section of
-     * the sensor, in reading order</p>
+     * the sensor, in reading order.</p>
      * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB
      * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG
      * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG
@@ -1372,8 +1378,11 @@
 
     /**
      * <p>The physical dimensions of the full pixel
-     * array</p>
-     * <p>Needed for FOV calculation for old API</p>
+     * array.</p>
+     * <p>This is the physical size of the sensor pixel
+     * array defined by {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
      */
     public static final Key<android.util.SizeF> SENSOR_INFO_PHYSICAL_SIZE =
             new Key<android.util.SizeF>("android.sensor.info.physicalSize", android.util.SizeF.class);
@@ -1381,9 +1390,17 @@
     /**
      * <p>Dimensions of full pixel array, possibly
      * including black calibration pixels.</p>
-     * <p>Maximum output resolution for raw format must
-     * match this in
-     * android.scaler.availableStreamConfigurations.</p>
+     * <p>The pixel count of the full pixel array,
+     * which covers {@link CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE android.sensor.info.physicalSize} area.</p>
+     * <p>If a camera device supports raw sensor formats, either this
+     * or {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is the maximum output
+     * raw size listed in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.
+     * If a size corresponding to pixelArraySize is listed, the resulting
+     * raw sensor image will include black pixels.</p>
+     *
+     * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PHYSICAL_SIZE
      */
     public static final Key<android.util.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE =
             new Key<android.util.Size>("android.sensor.info.pixelArraySize", android.util.Size.class);
@@ -1638,8 +1655,8 @@
             new Key<Integer>("android.sensor.orientation", 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>Lists the supported sensor test pattern modes for {@link CaptureRequest#SENSOR_TEST_PATTERN_MODE android.sensor.testPatternMode}.</p>
+     * <p>Optional. Defaults to [OFF].</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
@@ -1648,10 +1665,9 @@
             new Key<int[]>("android.sensor.availableTestPatternModes", 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>The face detection modes that are available
+     * for this camera device.</p>
+     * <p>OFF is always supported.</p>
      * <p>SIMPLE means the device supports the
      * android.statistics.faceRectangles and
      * android.statistics.faceScores outputs.</p>
@@ -1663,8 +1679,8 @@
             new Key<int[]>("android.statistics.info.availableFaceDetectModes", int[].class);
 
     /**
-     * <p>Maximum number of simultaneously detectable
-     * faces</p>
+     * <p>The 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);
@@ -1673,7 +1689,7 @@
      * <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
+     * only OFF.  If the hotpixel map is available, this will include both
      * the ON and OFF options.</p>
      *
      * @see CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index e9213c5..1f89d33 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -52,7 +52,7 @@
      * Create a request suitable for a camera preview window. Specifically, this
      * means that high frame rate is given priority over the highest-quality
      * post-processing. These requests would normally be used with the
-     * {@link #setRepeatingRequest} method.
+     * {@link CameraCaptureSession#setRepeatingRequest} method.
      *
      * @see #createCaptureRequest
      */
@@ -61,7 +61,7 @@
     /**
      * Create a request suitable for still image capture. Specifically, this
      * means prioritizing image quality over frame rate. These requests would
-     * commonly be used with the {@link #capture} method.
+     * commonly be used with the {@link CameraCaptureSession#capture} method.
      *
      * @see #createCaptureRequest
      */
@@ -71,7 +71,7 @@
      * Create a request suitable for video recording. Specifically, this means
      * that a stable frame rate is used, and post-processing is set for
      * recording quality. These requests would commonly be used with the
-     * {@link #setRepeatingRequest} method.
+     * {@link CameraCaptureSession#setRepeatingRequest} method.
      *
      * @see #createCaptureRequest
      */
@@ -81,8 +81,8 @@
      * Create a request suitable for still image capture while recording
      * video. Specifically, this means maximizing image quality without
      * disrupting the ongoing recording. These requests would commonly be used
-     * with the {@link #capture} method while a request based on
-     * {@link #TEMPLATE_RECORD} is is in use with {@link #setRepeatingRequest}.
+     * with the {@link CameraCaptureSession#capture} method while a request based on
+     * {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
      *
      * @see #createCaptureRequest
      */
@@ -132,116 +132,6 @@
     /**
      * <p>Set up a new output set of Surfaces for the camera device.</p>
      *
-     * <p>The configuration determines the set of potential output Surfaces for
-     * the camera device for each capture request. A given request may use all
-     * or a only some of the outputs. This method must be called before requests
-     * can be submitted to the camera with {@link #capture capture},
-     * {@link #captureBurst captureBurst},
-     * {@link #setRepeatingRequest setRepeatingRequest}, or
-     * {@link #setRepeatingBurst setRepeatingBurst}.</p>
-     *
-     * <p>Surfaces suitable for inclusion as a camera output can be created for
-     * various use cases and targets:</p>
-     *
-     * <ul>
-     *
-     * <li>For drawing to a {@link android.view.SurfaceView SurfaceView}: Set
-     *   the size of the Surface with
-     *   {@link android.view.SurfaceHolder#setFixedSize} to be one of the
-     *   supported
-     *   {@link StreamConfigurationMap#getOutputSizes(Class) processed sizes}
-     *   before calling {@link android.view.SurfaceHolder#getSurface}.</li>
-     *
-     * <li>For accessing through an OpenGL texture via a
-     *   {@link android.graphics.SurfaceTexture SurfaceTexture}: Set the size of
-     *   the SurfaceTexture with
-     *   {@link android.graphics.SurfaceTexture#setDefaultBufferSize} to be one
-     *   of the supported
-     *   {@link StreamConfigurationMap#getOutputSizes(Class) processed sizes}
-     *   before creating a Surface from the SurfaceTexture with
-     *   {@link Surface#Surface}.</li>
-     *
-     * <li>For recording with {@link android.media.MediaCodec}: Call
-     *   {@link android.media.MediaCodec#createInputSurface} after configuring
-     *   the media codec to use one of the
-     *   {@link StreamConfigurationMap#getOutputSizes(Class) processed sizes}
-     *   </li>
-     *
-     * <li>For recording with {@link android.media.MediaRecorder}: TODO</li>
-     *
-     * <li>For efficient YUV processing with {@link android.renderscript}:
-     *   Create a RenderScript
-     *   {@link android.renderscript.Allocation Allocation} with a supported YUV
-     *   type, the IO_INPUT flag, and one of the supported
-     *   {@link StreamConfigurationMap#getOutputSizes(int) processed sizes}. Then
-     *   obtain the Surface with
-     *   {@link android.renderscript.Allocation#getSurface}.</li>
-     *
-     * <li>For access to uncompressed or {@link ImageFormat#JPEG JPEG} data in the application:
-     * Create a {@link android.media.ImageReader} object with the desired
-     * {@link StreamConfigurationMap#getOutputFormats() image format}, and a size from the matching
-     * {@link StreamConfigurationMap#getOutputSizes(int) processed size} and {@code format}.
-     * Then obtain a {@link Surface} from it.</li>
-     * </ul>
-     *
-     * </p>
-     *
-     * <p>This function can take several hundred milliseconds to execute, since
-     * camera hardware may need to be powered on or reconfigured.</p>
-     *
-     * <p>The camera device will query each Surface's size and formats upon this
-     * call, so they must be set to a valid setting at this time (in particular:
-     * if the format is user-visible, it must be one of
-     * {@link StreamConfigurationMap#getOutputFormats}; and the size must be one of
-     * {@link StreamConfigurationMap#getOutputSizes(int)}).</p>
-     *
-     * <p>When this method is called with valid Surfaces, the device will transition to the {@link
-     * StateListener#onBusy busy state}. Once configuration is complete, the device will transition
-     * into the {@link StateListener#onIdle idle state}. Capture requests using the newly-configured
-     * Surfaces may then be submitted with {@link #capture}, {@link #captureBurst}, {@link
-     * #setRepeatingRequest}, or {@link #setRepeatingBurst}.</p>
-     *
-     * <p>If this method is called while the camera device is still actively processing previously
-     * submitted captures, then the following sequence of events occurs: The device transitions to
-     * the busy state and calls the {@link StateListener#onBusy} callback. Second, if a repeating
-     * request is set it is cleared.  Third, the device finishes up all in-flight and pending
-     * requests. Finally, once the device is idle, it then reconfigures its outputs, and calls the
-     * {@link StateListener#onIdle} method once it is again ready to accept capture
-     * requests. Therefore, no submitted work is discarded. To idle as fast as possible, use {@link
-     * #flush} and wait for the idle callback before calling configureOutputs. This will discard
-     * work, but reaches the new configuration sooner.</p>
-     *
-     * <p>Using larger resolution outputs, or more outputs, can result in slower
-     * output rate from the device.</p>
-     *
-     * <p>Configuring the outputs with an empty or null list will transition the camera into an
-     * {@link StateListener#onUnconfigured unconfigured state} instead of the {@link
-     * StateListener#onIdle idle state}.  </p>
-     *
-     * <p>Calling configureOutputs with the same arguments as the last call to
-     * configureOutputs has no effect, and the {@link StateListener#onBusy busy}
-     * and {@link StateListener#onIdle idle} state transitions will happen
-     * immediately.</p>
-     *
-     * @param outputs The new set of Surfaces that should be made available as
-     * targets for captured image data.
-     *
-     * @throws IllegalArgumentException if the set of output Surfaces do not
-     * meet the requirements
-     * @throws CameraAccessException if the camera device is no longer connected or has
-     *                               encountered a fatal error
-     * @throws IllegalStateException if the camera device is not idle, or
-     *                               if the camera device has been closed
-     *
-     * @see StateListener#onBusy
-     * @see StateListener#onIdle
-     * @see StateListener#onActive
-     * @see StateListener#onUnconfigured
-     * @see #stopRepeating
-     * @see #flush
-     * @see StreamConfigurationMap#getOutputFormats()
-     * @see StreamConfigurationMap#getOutputSizes(int)
-     * @see StreamConfigurationMap#getOutputSizes(Class)
      * @deprecated Use {@link #createCaptureSession} instead
      */
     @Deprecated
@@ -264,10 +154,11 @@
      *
      * <ul>
      *
-     * <li>For drawing to a {@link android.view.SurfaceView SurfaceView}: Set the size of the
-     *   Surface with {@link android.view.SurfaceHolder#setFixedSize} to be one of the sizes
-     *   returned by
-     *   {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceView.class)}
+     * <li>For drawing to a {@link android.view.SurfaceView SurfaceView}: Once the SurfaceView's
+     *   Surface is {@link android.view.SurfaceHolder.Callback#surfaceCreated created}, set the
+     *   size of the Surface with {@link android.view.SurfaceHolder#setFixedSize} to be one of the
+     *   sizes returned by
+     *   {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceHolder.class)}
      *   and then obtain the Surface by calling {@link android.view.SurfaceHolder#getSurface}.</li>
      *
      * <li>For accessing through an OpenGL texture via a
@@ -300,22 +191,18 @@
      *   Then obtain the Surface with
      *   {@link android.renderscript.Allocation#getSurface}.</li>
      *
-     * <li>For access to raw, uncompressed or JPEG data in the application: Create a
-     *   {@link android.media.ImageReader} object with the one of the supported
-     *   {@link StreamConfigurationMap#getOutputFormats() output image formats}, and a
-     *   size from the supported
-     *   {@link StreamConfigurationMap#getOutputSizes(int) sizes for that format}. Then obtain
-     *   a Surface from it with {@link android.media.ImageReader#getSurface}.</li>
+     * <li>For access to raw, uncompressed JPEG data in the application: Create an
+     *   {@link android.media.ImageReader} object with one of the supported output formats given by
+     *   {@link StreamConfigurationMap#getOutputFormats()}, setting its size to one of the
+     *   corresponding supported sizes by passing the chosen output format into
+     *   {@link StreamConfigurationMap#getOutputSizes(int)}. Then obtain a
+     *   {@link android.view.Surface} from it with {@link android.media.ImageReader#getSurface()}.
+     *   </li>
      *
      * </ul>
      *
-     * </p>
-     *
      * <p>The camera device will query each Surface's size and formats upon this
-     * call, so they must be set to a valid setting at this time (in particular:
-     * if the format is user-visible, it must be one of
-     * {@link StreamConfigurationMap#getOutputFormats}; and the size must be one of
-     * {@link StreamConfigurationMap#getOutputSizes(int)}).</p>
+     * call, so they must be set to a valid setting at this time.</p>
      *
      * <p>It can take several hundred milliseconds for the session's configuration to complete,
      * since camera hardware may need to be powered on or reconfigured. Once the configuration is
@@ -342,10 +229,7 @@
      * @param listener The listener to notify about the status of the new capture session.
      * @param handler The handler on which the listener should be invoked, or {@code null} to use
      *                the current thread's {@link android.os.Looper looper}.
-     * <!--
-     * @return A new camera capture session to use, or null if an empty/null set of Surfaces is
-     *         provided.
-     * -->
+     *
      * @throws IllegalArgumentException if the set of output Surfaces do not meet the requirements,
      *                                  the listener is null, or the handler is null but the current
      *                                  thread has no looper.
@@ -393,92 +277,16 @@
     /**
      * <p>Submit a request for an image to be captured by this CameraDevice.</p>
      *
-     * <p>The request defines all the parameters for capturing the single image,
-     * including sensor, lens, flash, and post-processing settings.</p>
-     *
-     * <p>Each request will produce one {@link CaptureResult} and produce new
-     * frames for one or more target Surfaces, set with the CaptureRequest
-     * builder's {@link CaptureRequest.Builder#addTarget} method. The target
-     * surfaces must be configured as active outputs with
-     * {@link #configureOutputs} before calling this method.</p>
-     *
-     * <p>Multiple requests can be in progress at once. They are processed in
-     * first-in, first-out order, with minimal delays between each
-     * capture. Requests submitted through this method have higher priority than
-     * those submitted through {@link #setRepeatingRequest} or
-     * {@link #setRepeatingBurst}, and will be processed as soon as the current
-     * repeat/repeatBurst processing completes.</p>
-     *
-     * @param request the settings for this capture
-     * @param listener The callback object to notify once this request has been
-     * processed. If null, no metadata will be produced for this capture,
-     * although image data will still be produced.
-     * @param handler the handler on which the listener should be invoked, or
-     * {@code null} to use the current thread's {@link android.os.Looper
-     * looper}.
-     *
-     * @return int A unique capture sequence ID used by
-     *             {@link CaptureListener#onCaptureSequenceCompleted}.
-     *
-     * @throws CameraAccessException if the camera device is no longer connected or has
-     *                               encountered a fatal error
-     * @throws IllegalStateException if the camera is currently busy or unconfigured,
-     *                               or the camera device has been closed.
-     * @throws IllegalArgumentException If the request targets Surfaces not
-     * currently configured as outputs. Or if the handler is null, the listener
-     * is not null, and the calling thread has no looper.
-     *
-     * @see #captureBurst
-     * @see #setRepeatingRequest
-     * @see #setRepeatingBurst
-     * @deprecated Use {@link CameraCaptureSession} instead
+     * @deprecated Use {@link CameraCaptureSession#capture} instead
      */
     @Deprecated
     public abstract int capture(CaptureRequest request, CaptureListener listener, Handler handler)
             throws CameraAccessException;
 
     /**
-     * Submit a list of requests to be captured in sequence as a burst. The
-     * burst will be captured in the minimum amount of time possible, and will
-     * not be interleaved with requests submitted by other capture or repeat
-     * calls.
+     * Submit a list of requests to be captured in sequence as a burst.
      *
-     * <p>The requests will be captured in order, each capture producing one
-     * {@link CaptureResult} and image buffers for one or more target
-     * {@link android.view.Surface surfaces}. The target surfaces for each
-     * request (set with {@link CaptureRequest.Builder#addTarget}) must be
-     * configured as active outputs with {@link #configureOutputs} before
-     * calling this method.</p>
-     *
-     * <p>The main difference between this method and simply calling
-     * {@link #capture} repeatedly is that this method guarantees that no
-     * other requests will be interspersed with the burst.</p>
-     *
-     * @param requests the list of settings for this burst capture
-     * @param listener The callback object to notify each time one of the
-     * requests in the burst has been processed. If null, no metadata will be
-     * produced for any requests in this burst, although image data will still
-     * be produced.
-     * @param handler the handler on which the listener should be invoked, or
-     * {@code null} to use the current thread's {@link android.os.Looper
-     * looper}.
-     *
-     * @return int A unique capture sequence ID used by
-     *             {@link CaptureListener#onCaptureSequenceCompleted}.
-     *
-     * @throws CameraAccessException if the camera device is no longer connected or has
-     *                               encountered a fatal error
-     * @throws IllegalStateException if the camera is currently busy or unconfigured,
-     *                               or the camera device has been closed.
-     * @throws IllegalArgumentException If the requests target Surfaces not
-     * currently configured as outputs. Or if the handler is null, the listener
-     * is not null, and the calling thread has no looper. Or if no requests were
-     * passed in.
-     *
-     * @see #capture
-     * @see #setRepeatingRequest
-     * @see #setRepeatingBurst
-     * @deprecated Use {@link CameraCaptureSession} instead
+     * @deprecated Use {@link CameraCaptureSession#captureBurst} instead
      */
     @Deprecated
     public abstract int captureBurst(List<CaptureRequest> requests, CaptureListener listener,
@@ -487,58 +295,7 @@
     /**
      * Request endlessly repeating capture of images by this CameraDevice.
      *
-     * <p>With this method, the CameraDevice will continually capture images
-     * using the settings in the provided {@link CaptureRequest}, at the maximum
-     * rate possible.</p>
-     *
-     * <p>Repeating requests are a simple way for an application to maintain a
-     * preview or other continuous stream of frames, without having to
-     * continually submit identical requests through {@link #capture}.</p>
-     *
-     * <p>Repeat requests have lower priority than those submitted
-     * through {@link #capture} or {@link #captureBurst}, so if
-     * {@link #capture} is called when a repeating request is active, the
-     * capture request will be processed before any further repeating
-     * requests are processed.<p>
-     *
-     * <p>Repeating requests are a simple way for an application to maintain a
-     * preview or other continuous stream of frames, without having to submit
-     * requests through {@link #capture} at video rates.</p>
-     *
-     * <p>To stop the repeating capture, call {@link #stopRepeating}. Calling
-     * {@link #flush} will also clear the request.</p>
-     *
-     * <p>Calling this method will replace any earlier repeating request or
-     * burst set up by this method or {@link #setRepeatingBurst}, although any
-     * in-progress burst will be completed before the new repeat request will be
-     * used.</p>
-     *
-     * @param request the request to repeat indefinitely
-     * @param listener The callback object to notify every time the
-     * request finishes processing. If null, no metadata will be
-     * produced for this stream of requests, although image data will
-     * still be produced.
-     * @param handler the handler on which the listener should be invoked, or
-     * {@code null} to use the current thread's {@link android.os.Looper
-     * looper}.
-     *
-     * @return int A unique capture sequence ID used by
-     *             {@link CaptureListener#onCaptureSequenceCompleted}.
-     *
-     * @throws CameraAccessException if the camera device is no longer connected or has
-     *                               encountered a fatal error
-     * @throws IllegalStateException if the camera is currently busy or unconfigured,
-     *                               or the camera device has been closed.
-     * @throws IllegalArgumentException If the requests reference Surfaces not
-     * currently configured as outputs. Or if the handler is null, the listener
-     * is not null, and the calling thread has no looper.
-     *
-     * @see #capture
-     * @see #captureBurst
-     * @see #setRepeatingBurst
-     * @see #stopRepeating
-     * @see #flush
-     * @deprecated Use {@link CameraCaptureSession} instead
+     * @deprecated Use {@link CameraCaptureSession#setRepeatingRequest} instead
      */
     @Deprecated
     public abstract int setRepeatingRequest(CaptureRequest request, CaptureListener listener,
@@ -548,58 +305,7 @@
      * <p>Request endlessly repeating capture of a sequence of images by this
      * CameraDevice.</p>
      *
-     * <p>With this method, the CameraDevice will continually capture images,
-     * cycling through the settings in the provided list of
-     * {@link CaptureRequest CaptureRequests}, at the maximum rate possible.</p>
-     *
-     * <p>If a request is submitted through {@link #capture} or
-     * {@link #captureBurst}, the current repetition of the request list will be
-     * completed before the higher-priority request is handled. This guarantees
-     * that the application always receives a complete repeat burst captured in
-     * minimal time, instead of bursts interleaved with higher-priority
-     * captures, or incomplete captures.</p>
-     *
-     * <p>Repeating burst requests are a simple way for an application to
-     * maintain a preview or other continuous stream of frames where each
-     * request is different in a predicatable way, without having to continually
-     * submit requests through {@link #captureBurst} .</p>
-     *
-     * <p>To stop the repeating capture, call {@link #stopRepeating}. Any
-     * ongoing burst will still be completed, however. Calling
-     * {@link #flush} will also clear the request.</p>
-     *
-     * <p>Calling this method will replace a previously-set repeating request or
-     * burst set up by this method or {@link #setRepeatingRequest}, although any
-     * in-progress burst will be completed before the new repeat burst will be
-     * used.</p>
-     *
-     * @param requests the list of requests to cycle through indefinitely
-     * @param listener The callback object to notify each time one of the
-     * requests in the repeating bursts has finished processing. If null, no
-     * metadata will be produced for this stream of requests, although image
-     * data will still be produced.
-     * @param handler the handler on which the listener should be invoked, or
-     * {@code null} to use the current thread's {@link android.os.Looper
-     * looper}.
-     *
-     * @return int A unique capture sequence ID used by
-     *             {@link CaptureListener#onCaptureSequenceCompleted}.
-     *
-     * @throws CameraAccessException if the camera device is no longer connected or has
-     *                               encountered a fatal error
-     * @throws IllegalStateException if the camera is currently busy or unconfigured,
-     *                               or the camera device has been closed.
-     * @throws IllegalArgumentException If the requests reference Surfaces not
-     * currently configured as outputs. Or if the handler is null, the listener
-     * is not null, and the calling thread has no looper. Or if no requests were
-     * passed in.
-     *
-     * @see #capture
-     * @see #captureBurst
-     * @see #setRepeatingRequest
-     * @see #stopRepeating
-     * @see #flush
-     * @deprecated Use {@link CameraCaptureSession} instead
+     * @deprecated Use {@link CameraCaptureSession#setRepeatingBurst} instead
      */
     @Deprecated
     public abstract int setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
@@ -608,24 +314,9 @@
     /**
      * <p>Cancel any ongoing repeating capture set by either
      * {@link #setRepeatingRequest setRepeatingRequest} or
-     * {@link #setRepeatingBurst}. Has no effect on requests submitted through
-     * {@link #capture capture} or {@link #captureBurst captureBurst}.</p>
+     * {@link #setRepeatingBurst}.
      *
-     * <p>Any currently in-flight captures will still complete, as will any
-     * burst that is mid-capture. To ensure that the device has finished
-     * processing all of its capture requests and is in idle state, wait for the
-     * {@link StateListener#onIdle} callback after calling this
-     * method..</p>
-     *
-     * @throws CameraAccessException if the camera device is no longer connected or has
-     *                               encountered a fatal error
-     * @throws IllegalStateException if the camera is currently busy or unconfigured,
-     *                               or the camera device has been closed.
-     *
-     * @see #setRepeatingRequest
-     * @see #setRepeatingBurst
-     * @see StateListener#onIdle
-     * @deprecated Use {@link CameraCaptureSession} instead
+     * @deprecated Use {@link CameraCaptureSession#stopRepeating} instead
      */
     @Deprecated
     public abstract void stopRepeating() throws CameraAccessException;
@@ -634,36 +325,7 @@
      * Flush all captures currently pending and in-progress as fast as
      * possible.
      *
-     * <p>The camera device will discard all of its current work as fast as
-     * possible. Some in-flight captures may complete successfully and call
-     * {@link CaptureListener#onCaptureCompleted}, while others will trigger
-     * their {@link CaptureListener#onCaptureFailed} callbacks. If a repeating
-     * request or a repeating burst is set, it will be cleared by the flush.</p>
-     *
-     * <p>This method is the fastest way to idle the camera device for
-     * reconfiguration with {@link #configureOutputs}, at the cost of discarding
-     * in-progress work. Once the flush is complete, the idle callback will be
-     * called.</p>
-     *
-     * <p>Flushing will introduce at least a brief pause in the stream of data
-     * from the camera device, since once the flush is complete, the first new
-     * request has to make it through the entire camera pipeline before new
-     * output buffers are produced.</p>
-     *
-     * <p>This means that using {@code flush()} to simply remove pending
-     * requests is not recommended; it's best used for quickly switching output
-     * configurations, or for cancelling long in-progress requests (such as a
-     * multi-second capture).</p>
-     *
-     * @throws CameraAccessException if the camera device is no longer connected or has
-     *                               encountered a fatal error
-     * @throws IllegalStateException if the camera is not idle/active,
-     *                               or the camera device has been closed.
-     *
-     * @see #setRepeatingRequest
-     * @see #setRepeatingBurst
-     * @see #configureOutputs
-     * @deprecated Use {@link CameraCaptureSession} instead
+     * @deprecated Use {@link CameraCaptureSession#abortCaptures} instead
      */
     @Deprecated
     public abstract void flush() throws CameraAccessException;
@@ -690,15 +352,7 @@
      * <p>A listener for tracking the progress of a {@link CaptureRequest}
      * submitted to the camera device.</p>
      *
-     * <p>This listener is called when a request triggers a capture to start,
-     * and when the capture is complete. In case on an error capturing an image,
-     * the error method is triggered instead of the completion method.</p>
-     *
-     * @see #capture
-     * @see #captureBurst
-     * @see #setRepeatingRequest
-     * @see #setRepeatingBurst
-     * @deprecated Use {@link CameraCaptureSession} instead
+     * @deprecated Use {@link CameraCaptureSession.CaptureListener} instead
      */
     @Deprecated
     public static abstract class CaptureListener {
@@ -715,29 +369,6 @@
          * This method is called when the camera device has started capturing
          * the output image for the request, at the beginning of image exposure.
          *
-         * <p>This callback is invoked right as the capture of a frame begins,
-         * so it is the most appropriate time for playing a shutter sound,
-         * or triggering UI indicators of capture.</p>
-         *
-         * <p>The request that is being used for this capture is provided, along
-         * with the actual timestamp for the start of exposure. This timestamp
-         * matches the timestamp that will be included in
-         * {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field},
-         * and in the buffers sent to each output Surface. These buffer
-         * timestamps are accessible through, for example,
-         * {@link android.media.Image#getTimestamp() Image.getTimestamp()} or
-         * {@link android.graphics.SurfaceTexture#getTimestamp()}.</p>
-         *
-         * <p>For the simplest way to play a shutter sound camera shutter or a
-         * video recording start/stop sound, see the
-         * {@link android.media.MediaActionSound} class.</p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera the CameraDevice sending the callback
-         * @param request the request for the capture that just begun
-         * @param timestamp the timestamp at start of capture, in nanoseconds.
-         *
          * @see android.media.MediaActionSound
          */
         public void onCaptureStarted(CameraDevice camera,
@@ -749,25 +380,6 @@
          * This method is called when some results from an image capture are
          * available.
          *
-         * <p>The result provided here will contain some subset of the fields of
-         * a full result. Multiple onCapturePartial calls may happen per
-         * capture; a given result field will only be present in one partial
-         * capture at most. The final onCaptureCompleted call will always
-         * contain all the fields, whether onCapturePartial was called or
-         * not.</p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera The CameraDevice sending the callback.
-         * @param request The request that was given to the CameraDevice
-         * @param result The partial output metadata from the capture, which
-         * includes a subset of the CaptureResult fields.
-         *
-         * @see #capture
-         * @see #captureBurst
-         * @see #setRepeatingRequest
-         * @see #setRepeatingBurst
-         *
          * @hide
          */
         public void onCapturePartial(CameraDevice camera,
@@ -779,37 +391,6 @@
          * This method is called when an image capture makes partial forward progress; some
          * (but not all) results from an image capture are available.
          *
-         * <p>The result provided here will contain some subset of the fields of
-         * a full result. Multiple {@link #onCaptureProgressed} calls may happen per
-         * capture; a given result field will only be present in one partial
-         * capture at most. The final {@link #onCaptureCompleted} call will always
-         * contain all the fields (in particular, the union of all the fields of all
-         * the partial results composing the total result).</p>
-         *
-         * <p>For each request, some result data might be available earlier than others. The typical
-         * delay between each partial result (per request) is a single frame interval.
-         * For performance-oriented use-cases, applications should query the metadata they need
-         * to make forward progress from the partial results and avoid waiting for the completed
-         * result.</p>
-         *
-         * <p>Each request will generate at least {@code 1} partial results, and at most
-         * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT} partial results.</p>
-         *
-         * <p>Depending on the request settings, the number of partial results per request
-         * will vary, although typically the partial count could be the same as long as the
-         * camera device subsystems enabled stay the same.</p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera The CameraDevice sending the callback.
-         * @param request The request that was given to the CameraDevice
-         * @param partialResult The partial output metadata from the capture, which
-         * includes a subset of the {@link TotalCaptureResult} fields.
-         *
-         * @see #capture
-         * @see #captureBurst
-         * @see #setRepeatingRequest
-         * @see #setRepeatingBurst
          */
         public void onCaptureProgressed(CameraDevice camera,
                 CaptureRequest request, CaptureResult partialResult) {
@@ -819,26 +400,6 @@
         /**
          * This method is called when an image capture has fully completed and all the
          * result metadata is available.
-         *
-         * <p>This callback will always fire after the last {@link #onCaptureProgressed};
-         * in other words, no more partial results will be delivered once the completed result
-         * is available.</p>
-         *
-         * <p>For performance-intensive use-cases where latency is a factor, consider
-         * using {@link #onCaptureProgressed} instead.</p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera The CameraDevice sending the callback.
-         * @param request The request that was given to the CameraDevice
-         * @param result The total output metadata from the capture, including the
-         * final capture parameters and the state of the camera system during
-         * capture.
-         *
-         * @see #capture
-         * @see #captureBurst
-         * @see #setRepeatingRequest
-         * @see #setRepeatingBurst
          */
         public void onCaptureCompleted(CameraDevice camera,
                 CaptureRequest request, TotalCaptureResult result) {
@@ -849,29 +410,6 @@
          * This method is called instead of {@link #onCaptureCompleted} when the
          * camera device failed to produce a {@link CaptureResult} for the
          * request.
-         *
-         * <p>Other requests are unaffected, and some or all image buffers from
-         * the capture may have been pushed to their respective output
-         * streams.</p>
-         *
-         * <p>Some partial results may have been delivered before the capture fails;
-         * however after this callback fires, no more partial results will be delivered by
-         * {@link #onCaptureProgressed}.</p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera
-         *            The CameraDevice sending the callback.
-         * @param request
-         *            The request that was given to the CameraDevice
-         * @param failure
-         *            The output failure from the capture, including the failure reason
-         *            and the frame number.
-         *
-         * @see #capture
-         * @see #captureBurst
-         * @see #setRepeatingRequest
-         * @see #setRepeatingBurst
          */
         public void onCaptureFailed(CameraDevice camera,
                 CaptureRequest request, CaptureFailure failure) {
@@ -882,26 +420,6 @@
          * This method is called independently of the others in CaptureListener,
          * when a capture sequence finishes and all {@link CaptureResult}
          * or {@link CaptureFailure} for it have been returned via this listener.
-         *
-         * <p>In total, there will be at least one result/failure returned by this listener
-         * before this callback is invoked. If the capture sequence is aborted before any
-         * requests have been processed, {@link #onCaptureSequenceAborted} is invoked instead.</p>
-         *
-         * <p>The default implementation does nothing.</p>
-         *
-         * @param camera
-         *            The CameraDevice sending the callback.
-         * @param sequenceId
-         *            A sequence ID returned by the {@link #capture} family of functions.
-         * @param frameNumber
-         *            The last frame number (returned by {@link CaptureResult#getFrameNumber}
-         *            or {@link CaptureFailure#getFrameNumber}) in the capture sequence.
-         *
-         * @see CaptureResult#getFrameNumber()
-         * @see CaptureFailure#getFrameNumber()
-         * @see CaptureResult#getSequenceId()
-         * @see CaptureFailure#getSequenceId()
-         * @see #onCaptureSequenceAborted
          */
         public void onCaptureSequenceCompleted(CameraDevice camera,
                 int sequenceId, long frameNumber) {
@@ -912,25 +430,6 @@
          * This method is called independently of the others in CaptureListener,
          * when a capture sequence aborts before any {@link CaptureResult}
          * or {@link CaptureFailure} for it have been returned via this listener.
-         *
-         * <p>Due to the asynchronous nature of the camera device, not all submitted captures
-         * are immediately processed. It is possible to clear out the pending requests
-         * by a variety of operations such as {@link CameraDevice#stopRepeating} or
-         * {@link CameraDevice#flush}. When such an event happens,
-         * {@link #onCaptureSequenceCompleted} will not be called.</p>
-         *
-         * <p>The default implementation does nothing.</p>
-         *
-         * @param camera
-         *            The CameraDevice sending the callback.
-         * @param sequenceId
-         *            A sequence ID returned by the {@link #capture} family of functions.
-         *
-         * @see CaptureResult#getFrameNumber()
-         * @see CaptureFailure#getFrameNumber()
-         * @see CaptureResult#getSequenceId()
-         * @see CaptureFailure#getSequenceId()
-         * @see #onCaptureSequenceCompleted
          */
         public void onCaptureSequenceAborted(CameraDevice camera,
                 int sequenceId) {
@@ -945,14 +444,14 @@
      * <p>A listener must be provided to the {@link CameraManager#openCamera}
      * method to open a camera device.</p>
      *
-     * <p>These events include notifications about the device becoming idle (
-     * allowing for {@link #configureOutputs} to be called), about device
-     * disconnection, and about unexpected device errors.</p>
+     * <p>These events include notifications about the device completing startup (
+     * allowing for {@link #createCaptureSession} to be called), about device
+     * disconnection or closure, and about unexpected device errors.</p>
      *
-     * <p>Events about the progress of specific {@link CaptureRequest
-     * CaptureRequests} are provided through a {@link CaptureListener} given to
-     * the {@link #capture}, {@link #captureBurst}, {@link
-     * #setRepeatingRequest}, or {@link #setRepeatingBurst} methods.
+     * <p>Events about the progress of specific {@link CaptureRequest CaptureRequests} are provided
+     * through a {@link CameraCaptureSession.CaptureListener} given to the
+     * {@link CameraCaptureSession#capture}, {@link CameraCaptureSession#captureBurst},
+     * {@link CameraCaptureSession#setRepeatingRequest}, or {@link CameraCaptureSession#setRepeatingBurst} methods.
      *
      * @see CameraManager#openCamera
      */
@@ -1026,8 +525,9 @@
         /**
          * The method called when a camera device has finished opening.
          *
-         * <p>An opened camera will immediately afterwards transition into
-         * {@link #onUnconfigured}.</p>
+         * <p>At this point, the camera device is ready to use, and
+         * {@link CameraDevice#createCaptureSession} can be called to set up the first capture
+         * session.</p>
          *
          * @param camera the camera device that has become opened
          */
@@ -1036,21 +536,7 @@
         /**
          * The method called when a camera device has no outputs configured.
          *
-         * <p>An unconfigured camera device needs to be configured with
-         * {@link CameraDevice#configureOutputs} before being able to
-         * submit any capture request.</p>
-         *
-         * <p>This state may be entered by a newly opened camera or by
-         * calling {@link CameraDevice#configureOutputs} with a null/empty
-         * list of Surfaces when idle.</p>
-         *
-         * <p>Any attempts to submit a capture request while in this state
-         * will result in an {@link IllegalStateException} being thrown.</p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera the camera device has that become unconfigured
-         * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
+         * @deprecated Use {@link #onOpened} instead.
          */
         @Deprecated
         public void onUnconfigured(CameraDevice camera) {
@@ -1061,27 +547,7 @@
          * The method called when a camera device begins processing
          * {@link CaptureRequest capture requests}.
          *
-         * <p>A camera may not be re-configured while in this state. The camera
-         * will transition to the idle state once all pending captures have
-         * completed. If a repeating request is set, the camera will remain active
-         * until it is cleared and the remaining requests finish processing. To
-         * transition to the idle state as quickly as possible, call {@link #flush()},
-         * which will idle the camera device as quickly as possible, likely canceling
-         * most in-progress captures.</p>
-         *
-         * <p>All calls except for {@link CameraDevice#configureOutputs} are
-         * legal while in this state.
-         * </p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera the camera device that has become active
-         *
-         * @see CameraDevice#capture
-         * @see CameraDevice#captureBurst
-         * @see CameraDevice#setRepeatingBurst
-         * @see CameraDevice#setRepeatingRequest
-         * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
+         * @deprecated Use {@link CameraCaptureSession.StateListener#onActive} instead.
          */
         @Deprecated
         public void onActive(CameraDevice camera) {
@@ -1091,32 +557,7 @@
         /**
          * The method called when a camera device is busy.
          *
-         * <p>A camera becomes busy while it's outputs are being configured
-         * (after a call to {@link CameraDevice#configureOutputs} or while it's
-         * being flushed (after a call to {@link CameraDevice#flush}.</p>
-         *
-         * <p>Once the on-going operations are complete, the camera will automatically
-         * transition into {@link #onIdle} if there is at least one configured output,
-         * or {@link #onUnconfigured} otherwise.</p>
-         *
-         * <p>Any attempts to manipulate the camera while its is busy
-         * will result in an {@link IllegalStateException} being thrown.</p>
-         *
-         * <p>Only the following methods are valid to call while in this state:
-         * <ul>
-         * <li>{@link CameraDevice#getId}</li>
-         * <li>{@link CameraDevice#createCaptureRequest}</li>
-         * <li>{@link CameraDevice#close}</li>
-         * </ul>
-         * </p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera the camera device that has become busy
-         *
-         * @see CameraDevice#configureOutputs
-         * @see CameraDevice#flush
-         * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
+         * @deprecated Use {@link CameraCaptureSession.StateListener#onConfigured} instead.
          */
         @Deprecated
         public void onBusy(CameraDevice camera) {
@@ -1142,30 +583,7 @@
          * The method called when a camera device has finished processing all
          * submitted capture requests and has reached an idle state.
          *
-         * <p>An idle camera device can have its outputs changed by calling {@link
-         * CameraDevice#configureOutputs}, which will transition it into the busy state.</p>
-         *
-         * <p>To idle and reconfigure outputs without canceling any submitted
-         * capture requests, the application needs to clear its repeating
-         * request/burst, if set, with {@link CameraDevice#stopRepeating}, and
-         * then wait for this callback to be called before calling {@link
-         * CameraDevice#configureOutputs}.</p>
-         *
-         * <p>To idle and reconfigure a camera device as fast as possible, the
-         * {@link CameraDevice#flush} method can be used, which will discard all
-         * pending and in-progress capture requests. Once the {@link
-         * CameraDevice#flush} method is called, the application must wait for
-         * this callback to fire before calling {@link
-         * CameraDevice#configureOutputs}.</p>
-         *
-         * <p>The default implementation of this method does nothing.</p>
-         *
-         * @param camera the camera device that has become idle
-         *
-         * @see CameraDevice#configureOutputs
-         * @see CameraDevice#stopRepeating
-         * @see CameraDevice#flush
-         * @deprecated Use {@link CameraCaptureSession.StateListener} instead.
+         * @deprecated Use {@link CameraCaptureSession.StateListener#onReady} instead.
          */
         @Deprecated
         public void onIdle(CameraDevice camera) {
@@ -1221,7 +639,7 @@
          *
          * @param camera The device reporting the error
          * @param error The error code, one of the
-         *     {@code CameraDeviceListener.ERROR_*} values.
+         *     {@code StateListener.ERROR_*} values.
          *
          * @see #ERROR_CAMERA_DEVICE
          * @see #ERROR_CAMERA_SERVICE
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 9046b13..a69a813 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -35,7 +35,7 @@
 import java.util.ArrayList;
 
 /**
- * <p>An interface for iterating, listing, and connecting to
+ * <p>A system service manager for detecting, characterizing, and connecting to
  * {@link CameraDevice CameraDevices}.</p>
  *
  * <p>You can get an instance of this class by calling
@@ -244,11 +244,7 @@
                             USE_CALLING_UID, holder);
                     cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
                 } catch (CameraRuntimeException e) {
-                    if (e.getReason() == CameraAccessException.CAMERA_DEPRECATED_HAL) {
-                        // Use legacy camera implementation for HAL1 devices
-                        Log.i(TAG, "Using legacy camera HAL.");
-                        cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
-                    } else if (e.getReason() == CameraAccessException.CAMERA_IN_USE ||
+                    if (e.getReason() == CameraAccessException.CAMERA_IN_USE ||
                             e.getReason() == CameraAccessException.MAX_CAMERAS_IN_USE ||
                             e.getReason() == CameraAccessException.CAMERA_DISABLED ||
                             e.getReason() == CameraAccessException.CAMERA_DISCONNECTED ||
@@ -358,14 +354,18 @@
     }
 
     /**
-     * Interface for listening to camera devices becoming available or
-     * unavailable.
+     * A listener for camera devices becoming available or
+     * unavailable to open.
      *
      * <p>Cameras become available when they are no longer in use, or when a new
      * removable camera is connected. They become unavailable when some
      * application or service starts using a camera, or when a removable camera
      * is disconnected.</p>
      *
+     * <p>Extend this listener and pass an instance of the subclass to
+     * {@link CameraManager#addAvailabilityListener} to be notified of such availability
+     * changes.</p>
+     *
      * @see addAvailabilityListener
      */
     public static abstract class AvailabilityListener {
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 94a5a79..33e1915 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -157,8 +157,8 @@
 
     /**
      * <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
+     * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} do not correspond to any physical units.</p>
+     * <p>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
@@ -172,20 +172,24 @@
     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>
+     * <p>The lens focus distance is measured in diopters.</p>
+     * <p>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>
+     * <p>The lens focus distance is measured in diopters, and
+     * is calibrated.</p>
+     * <p>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;
@@ -195,11 +199,13 @@
     //
 
     /**
+     * <p>The camera device faces the same direction as the device's screen.</p>
      * @see CameraCharacteristics#LENS_FACING
      */
     public static final int LENS_FACING_FRONT = 0;
 
     /**
+     * <p>The camera device faces the opposite direction as the device's screen.</p>
      * @see CameraCharacteristics#LENS_FACING
      */
     public static final int LENS_FACING_BACK = 1;
@@ -215,11 +221,10 @@
      * <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
+     * @hide
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0;
 
@@ -228,15 +233,14 @@
      * 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
+     * @hide
      */
     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).
+     * as auto-exposure, and auto-focus can be bypassed).
      * The camera device supports basic manual control of the sensor image
      * acquisition related stages. This means the following controls are
      * guaranteed to be supported:</p>
@@ -257,11 +261,11 @@
      * <li>{@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</li>
      * </ul>
      * </li>
-     * <li>Manual lens control<ul>
+     * <li>Manual lens control (if the lens is adjustable)<ul>
      * <li>android.lens.*</li>
      * </ul>
      * </li>
-     * <li>Manual flash control<ul>
+     * <li>Manual flash control (if a flash unit is present)<ul>
      * <li>android.flash.*</li>
      * </ul>
      * </li>
@@ -312,8 +316,6 @@
      * </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>
      * <p>A given camera device may also support additional post-processing
      * controls, but this capability only covers the above list of controls.</p>
      *
@@ -340,8 +342,8 @@
      * (both input/output) will match the maximum available
      * resolution of JPEG streams.</li>
      * </ul>
-     * <p>@hide this, TODO: remove it when input related APIs are ready.</p>
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @hide
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4;
 
@@ -355,12 +357,14 @@
      * <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>
+     * input/output) will match either the value in
+     * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize} or
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</li>
      * <li>All DNG-related optional metadata entries are provided
      * by the camera device.</li>
      * </ul>
      *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      */
@@ -371,13 +375,13 @@
     //
 
     /**
-     * <p>The camera device will only support centered crop regions.</p>
+     * <p>The camera device only supports centered crop regions.</p>
      * @see CameraCharacteristics#SCALER_CROPPING_TYPE
      */
     public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0;
 
     /**
-     * <p>The camera device will support arbitrarily chosen crop regions.</p>
+     * <p>The camera device supports arbitrarily chosen crop regions.</p>
      * @see CameraCharacteristics#SCALER_CROPPING_TYPE
      */
     public static final int SCALER_CROPPING_TYPE_FREEFORM = 1;
@@ -523,7 +527,7 @@
     //
 
     /**
-     * <p>android.led.transmit control is used</p>
+     * <p>android.led.transmit control is used.</p>
      * @see CameraCharacteristics#LED_AVAILABLE_LEDS
      * @hide
      */
@@ -534,11 +538,14 @@
     //
 
     /**
+     * <p>This camera device has only limited capabilities.</p>
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0;
 
     /**
+     * <p>This camera device is capable of supporting advanced imaging
+     * applications.</p>
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1;
@@ -548,9 +555,9 @@
     //
 
     /**
-     * <p>Every frame has the requests immediately applied.
-     * (and furthermore for all results,
-     * <code>android.sync.frameNumber == android.request.frameCount</code>)</p>
+     * <p>Every frame has the requests immediately applied.</p>
+     * <p>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>
@@ -590,8 +597,8 @@
     public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0;
 
     /**
-     * <p>Must not slow down capture rate relative to sensor raw
-     * output.</p>
+     * <p>Color correction processing 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
@@ -604,8 +611,9 @@
     public static final int COLOR_CORRECTION_MODE_FAST = 1;
 
     /**
-     * <p>Capture rate (relative to sensor raw output)
-     * may be reduced by high quality.</p>
+     * <p>Color correction processing operates at improved
+     * quality but reduced 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
@@ -656,8 +664,8 @@
     //
 
     /**
-     * <p>The camera device's autoexposure routine is disabled;
-     * the application-selected {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * <p>The camera device's autoexposure routine is disabled.</p>
+     * <p>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
@@ -672,7 +680,8 @@
 
     /**
      * <p>The camera device's autoexposure routine is active,
-     * with no flash control. The application's values for
+     * with no flash control.</p>
+     * <p>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
@@ -689,10 +698,10 @@
     /**
      * <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
+     * conditions.</p>
+     * <p>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>
      *
@@ -705,10 +714,10 @@
     /**
      * <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
+     * captures.</p>
+     * <p>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>
      *
@@ -720,9 +729,10 @@
 
     /**
      * <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>
+     * reduction.</p>
+     * <p>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;
@@ -739,8 +749,9 @@
 
     /**
      * <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>
+     * by the camera device.</p>
+     * <p>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;
@@ -752,7 +763,7 @@
     /**
      * <p>The auto-focus routine does not control the lens;
      * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} is controlled by the
-     * application</p>
+     * application.</p>
      *
      * @see CaptureRequest#LENS_FOCUS_DISTANCE
      * @see CaptureRequest#CONTROL_AF_MODE
@@ -760,12 +771,14 @@
     public static final int CONTROL_AF_MODE_OFF = 0;
 
     /**
-     * <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
+     * <p>Basic automatic focus mode.</p>
+     * <p>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
+     * is activated, AF will transition to ACTIVE_SCAN, then to
      * the outcome of the scan (FOCUSED or NOT_FOCUSED).</p>
+     * <p>Always supported 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.</p>
      * <p>Triggering AF_CANCEL resets the lens position to default,
      * and sets the AF state to INACTIVE.</p>
      *
@@ -775,11 +788,16 @@
     public static final int CONTROL_AF_MODE_AUTO = 1;
 
     /**
+     * <p>Close-up focusing mode.</p>
      * <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
+     * autofocus trigger action is called. When that trigger is
+     * activated, AF will transition to ACTIVE_SCAN, then to
+     * the outcome of the scan (FOCUSED or NOT_FOCUSED). This
+     * mode is optimized for focusing on objects very close to
+     * the camera.</p>
+     * <p>When that trigger is activated, AF will transition to
      * ACTIVE_SCAN, then to the outcome of the scan (FOCUSED or
-     * NOT_FOCUSED).  Triggering cancel AF resets the lens
+     * NOT_FOCUSED). Triggering cancel AF resets the lens
      * position to default, and sets the AF state to
      * INACTIVE.</p>
      * @see CaptureRequest#CONTROL_AF_MODE
@@ -830,8 +848,11 @@
     public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4;
 
     /**
-     * <p>Extended depth of field (digital focus). AF
-     * trigger is ignored, AF state should always be
+     * <p>Extended depth of field (digital focus) mode.</p>
+     * <p>The camera device will produce images with an extended
+     * depth of field automatically; no special focusing
+     * operations need to be done before taking a picture.</p>
+     * <p>AF triggers are ignored, and the AF state will always be
      * INACTIVE.</p>
      * @see CaptureRequest#CONTROL_AF_MODE
      */
@@ -865,8 +886,8 @@
     //
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
-     * the application-selected color transform matrix
+     * <p>The camera device's auto-white balance routine is disabled.</p>
+     * <p>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>
@@ -878,9 +899,12 @@
     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>
+     * <p>The camera device's auto-white balance routine is active.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_GAINS
      * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
@@ -889,65 +913,125 @@
     public static final int CONTROL_AWB_MODE_AUTO = 1;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <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>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant A.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @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;
+     * <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>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant F2.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @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;
+     * <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>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant F4.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @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;
+     * <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>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant D65.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @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;
+     * <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>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @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;
+     * <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>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @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;
+     * <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>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_SHADE = 8;
@@ -957,38 +1041,43 @@
     //
 
     /**
-     * <p>This request doesn't fall into the other
-     * categories. Default to preview-like
+     * <p>The goal of this request doesn't fall into the other
+     * categories. The camera device will default to preview-like
      * behavior.</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0;
 
     /**
-     * <p>This request is for a preview-like usecase. The
-     * precapture trigger may be used to start off a metering
-     * w/flash sequence</p>
+     * <p>This request is for a preview-like use case.</p>
+     * <p>The precapture trigger may be used to start off a metering
+     * w/flash sequence.</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1;
 
     /**
      * <p>This request is for a still capture-type
-     * usecase.</p>
+     * use case.</p>
+     * <p>If the flash unit is under automatic control, it may fire as needed.</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>
+     * use case.</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>
+     * image while recording video) use case.</p>
+     * <p>The camera device should take the highest-quality image
+     * possible (given the other settings) without disrupting the
+     * frame rate of video recording.<br />
+     * </p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4;
@@ -997,15 +1086,16 @@
      * <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;
 
     /**
      * <p>This request is for manual capture use case where
-     * the applications want to directly control the capture parameters
-     * (e.g. {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}, {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} etc.).</p>
+     * the applications want to directly control the capture parameters.</p>
+     * <p>For example, the application may wish to manually control
+     * {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}, {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, etc.</p>
      *
      * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      * @see CaptureRequest#SENSOR_SENSITIVITY
@@ -1025,7 +1115,8 @@
 
     /**
      * <p>A "monocolor" effect where the image is mapped into
-     * a single color.  This will typically be grayscale.</p>
+     * a single color.</p>
+     * <p>This will typically be grayscale.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_MONO = 1;
@@ -1085,31 +1176,42 @@
     //
 
     /**
-     * <p>Full application control of pipeline. All 3A
-     * routines are disabled, no other settings in
-     * android.control.* have any effect</p>
+     * <p>Full application control of pipeline.</p>
+     * <p>All control by the device's metering and focusing (3A)
+     * routines is disabled, and no other settings in
+     * android.control.* have any effect, except that
+     * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} may be used by the camera
+     * device to select post-processing values for processing
+     * blocks that do not allow for manual control, or are not
+     * exposed by the camera API.</p>
+     * <p>However, the camera device's 3A routines may continue to
+     * collect statistics and update their internal state so that
+     * when control is switched to AUTO mode, good control values
+     * can be immediately applied.</p>
+     *
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      * @see CaptureRequest#CONTROL_MODE
      */
     public static final int CONTROL_MODE_OFF = 0;
 
     /**
-     * <p>Use settings for each individual 3A routine.
-     * Manual control of capture parameters is disabled. All
+     * <p>Use settings for each individual 3A routine.</p>
+     * <p>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
-     * control.aeMode, control.awbMode and control.afMode
-     * 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 scene mode is supported
-     * (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes} contain some modes
-     * other than DISABLED).</p>
+     * <p>Use a specific scene mode.</p>
+     * <p>Enabling this disables control.aeMode, control.awbMode and
+     * control.afMode 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 scene mode is
+     * supported (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}
+     * contain some modes other than DISABLED).</p>
      *
      * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
      * @see CaptureRequest#CONTROL_MODE
@@ -1119,7 +1221,12 @@
     /**
      * <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>
+     * auto-focus algorithms (3A) to update their statistics.</p>
+     * <p>Specifically, the 3A routines are locked to the last
+     * values set from a request with AUTO, OFF, or
+     * USE_SCENE_MODE, and any statistics or state updates
+     * collected from manual captures with OFF_KEEP_STATE will be
+     * discarded by the camera device.</p>
      * @see CaptureRequest#CONTROL_MODE
      */
     public static final int CONTROL_MODE_OFF_KEEP_STATE = 3;
@@ -1137,8 +1244,9 @@
     /**
      * <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),
+     * auto-exposure routines.</p>
+     * <p>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},
@@ -1154,8 +1262,8 @@
     public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1;
 
     /**
-     * <p>Optimized for photos of quickly moving objects.
-     * Similar to SPORTS.</p>
+     * <p>Optimized for photos of quickly moving objects.</p>
+     * <p>Similar to SPORTS.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_ACTION = 2;
@@ -1224,8 +1332,8 @@
     public static final int CONTROL_SCENE_MODE_FIREWORKS = 12;
 
     /**
-     * <p>Optimized for photos of quickly moving people.
-     * Similar to ACTION.</p>
+     * <p>Optimized for photos of quickly moving people.</p>
+     * <p>Similar to ACTION.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_SPORTS = 13;
@@ -1257,11 +1365,13 @@
     //
 
     /**
+     * <p>Video stabilization is disabled.</p>
      * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
      */
     public static final int CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0;
 
     /**
+     * <p>Video stabilization is enabled.</p>
      * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
      */
     public static final int CONTROL_VIDEO_STABILIZATION_MODE_ON = 1;
@@ -1271,21 +1381,20 @@
     //
 
     /**
-     * <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 sensor
+     * <p>Apply edge enhancement at a quality level that does 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>Apply high-quality edge enhancement, at a cost of reducing output frame rate.</p>
      * @see CaptureRequest#EDGE_MODE
      */
     public static final int EDGE_MODE_HIGH_QUALITY = 2;
@@ -1318,10 +1427,10 @@
     //
 
     /**
+     * <p>No hot pixel correction is applied.</p>
      * <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>
+     * <p>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
@@ -1329,10 +1438,9 @@
     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>
+     * <p>Hot pixel correction is applied, without reducing frame
+     * rate relative to sensor raw output.</p>
+     * <p>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
@@ -1340,10 +1448,9 @@
     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>
+     * <p>High-quality hot pixel correction is applied, at a cost
+     * of reducing frame rate relative to sensor raw output.</p>
+     * <p>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
@@ -1371,21 +1478,21 @@
     //
 
     /**
-     * <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 sensor
-     * output</p>
+     * <p>Noise reduction is applied without reducing 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>High-quality noise reduction is applied, at the cost of reducing frame rate
+     * relative to sensor output.</p>
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      */
     public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2;
@@ -1395,8 +1502,9 @@
     //
 
     /**
-     * <p>Default. No test pattern mode is used, and the camera
+     * <p>No test pattern mode is used, and the camera
      * device returns captures from the image sensor.</p>
+     * <p>This is the default if the key is not set.</p>
      * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
      */
     public static final int SENSOR_TEST_PATTERN_MODE_OFF = 0;
@@ -1500,19 +1608,21 @@
     //
 
     /**
-     * <p>No lens shading correction is applied</p>
+     * <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>
+     * <p>Apply lens shading corrections, without slowing
+     * 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>
+     * <p>Apply high-quality lens shading correction, at the
+     * cost of reduced frame rate.</p>
      * @see CaptureRequest#SHADING_MODE
      */
     public static final int SHADING_MODE_HIGH_QUALITY = 2;
@@ -1522,20 +1632,28 @@
     //
 
     /**
+     * <p>Do not include face detection statistics in capture
+     * results.</p>
      * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      */
     public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0;
 
     /**
-     * <p>Optional Return rectangle and confidence
-     * only</p>
+     * <p>Return face rectangle and confidence values only.</p>
+     * <p>In this mode, only android.statistics.faceRectangles and
+     * android.statistics.faceScores outputs are valid.</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>Return all face
+     * metadata.</p>
+     * <p>In this mode,
+     * android.statistics.faceRectangles,
+     * android.statistics.faceScores,
+     * android.statistics.faceIds, and
+     * android.statistics.faceLandmarks outputs are valid.</p>
      * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      */
     public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
@@ -1545,11 +1663,13 @@
     //
 
     /**
+     * <p>Do not include a lens shading map in the capture result.</p>
      * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
      */
     public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0;
 
     /**
+     * <p>Include a lens shading map in the capture result.</p>
      * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
      */
     public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1;
@@ -1573,15 +1693,15 @@
     public static final int TONEMAP_MODE_CONTRAST_CURVE = 0;
 
     /**
-     * <p>Advanced gamma mapping and color enhancement may be applied.</p>
-     * <p>Should not slow down frame rate relative to raw sensor output.</p>
+     * <p>Advanced gamma mapping and color enhancement may be applied, without
+     * reducing frame rate compared to raw sensor output.</p>
      * @see CaptureRequest#TONEMAP_MODE
      */
     public static final int TONEMAP_MODE_FAST = 1;
 
     /**
-     * <p>Advanced gamma mapping and color enhancement may be applied.</p>
-     * <p>May slow down frame rate relative to raw sensor output.</p>
+     * <p>High-quality gamma mapping and color enhancement will be applied, at
+     * the cost of reduced frame rate compared to raw sensor output.</p>
      * @see CaptureRequest#TONEMAP_MODE
      */
     public static final int TONEMAP_MODE_HIGH_QUALITY = 2;
@@ -1591,7 +1711,8 @@
     //
 
     /**
-     * <p>AE is off or recently reset. When a camera device is opened, it starts in
+     * <p>AE is off or recently reset.</p>
+     * <p>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
@@ -1600,7 +1721,8 @@
 
     /**
      * <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
+     * for the current scene.</p>
+     * <p>This is a transient state, the camera device may skip
      * reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AE_STATE
      */
@@ -1629,11 +1751,13 @@
 
     /**
      * <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. This is a transient state, the
-     * camera device may skip reporting this state in capture result.</p>
+     * and is currently executing it.</p>
+     * <p>Precapture can be triggered through setting
+     * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} to START.</p>
+     * <p>Once PRECAPTURE completes, AE will transition to CONVERGED
+     * or 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
@@ -1645,61 +1769,78 @@
     //
 
     /**
-     * <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. This is a transient state, the camera device may
-     * skip reporting this state in capture result.</p>
+     * <p>AF is off or has not yet tried to scan/been asked
+     * to scan.</p>
+     * <p>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_AF_STATE
      */
     public static final int CONTROL_AF_STATE_INACTIVE = 0;
 
     /**
-     * <p>if CONTINUOUS_* modes are supported. AF is
-     * currently doing an AF scan initiated by a continuous
-     * autofocus mode. This is a transient state, the camera device may
-     * skip reporting this state in capture result.</p>
+     * <p>AF is currently performing an AF scan initiated the
+     * camera device in a continuous autofocus mode.</p>
+     * <p>Only used by CONTINUOUS_* AF modes. 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
-     * believes it is in focus, but may restart scanning at
-     * any time. This is a transient state, the camera device may skip
-     * reporting this state in capture result.</p>
+     * <p>AF currently believes it is in focus, but may
+     * restart scanning at any time.</p>
+     * <p>Only used by CONTINUOUS_* AF modes. 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. This is a
-     * transient state, the camera device may skip reporting
-     * this state in capture result.</p>
+     * <p>AF is performing an AF scan because it was
+     * triggered by AF trigger.</p>
+     * <p>Only used by AUTO or MACRO AF modes. 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
-     * believes it is focused correctly and is
-     * locked.</p>
+     * <p>AF believes it is focused correctly and has locked
+     * focus.</p>
+     * <p>This state is reached only after an explicit START AF trigger has been
+     * sent ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}), when good focus has been obtained.</p>
+     * <p>The lens will remain stationary until the AF mode ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) is changed or
+     * a new AF trigger is sent to the camera device ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}).</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AF_TRIGGER
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4;
 
     /**
-     * <p>if any AF mode besides OFF is supported. AF has
-     * failed to focus successfully and is
-     * locked.</p>
+     * <p>AF has failed to focus successfully and has locked
+     * focus.</p>
+     * <p>This state is reached only after an explicit START AF trigger has been
+     * sent ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}), when good focus cannot be obtained.</p>
+     * <p>The lens will remain stationary until the AF mode ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) is changed or
+     * a new AF trigger is sent to the camera device ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}).</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AF_TRIGGER
      * @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
-     * passive scan without finding focus, and may restart
-     * scanning at any time. This is a transient state, the camera
+     * <p>AF finished a passive scan without finding focus,
+     * and may restart scanning at any time.</p>
+     * <p>Only used by CONTINUOUS_* AF modes. This is a transient state, the camera
      * device may skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
@@ -1710,16 +1851,19 @@
     //
 
     /**
-     * <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>
+     * <p>AWB is not in auto mode, or has not yet started metering.</p>
+     * <p>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. This is a transient state, the camera device
+     * values for the current scene.</p>
+     * <p>This is a transient state, the camera device
      * may skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AWB_STATE
      */
@@ -1767,8 +1911,9 @@
     public static final int FLASH_STATE_FIRED = 3;
 
     /**
-     * <p>Flash partially illuminated this frame. This is usually due to the next
-     * or previous frame having the flash fire, and the flash spilling into this capture
+     * <p>Flash partially illuminated this frame.</p>
+     * <p>This is usually due to the next or previous frame having
+     * the flash fire, and the flash spilling into this capture
      * due to hardware limitations.</p>
      * @see CaptureResult#FLASH_STATE
      */
@@ -1791,8 +1936,10 @@
     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>
+     * <p>One or several 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
+     * currently changing.</p>
      *
      * @see CaptureRequest#LENS_APERTURE
      * @see CaptureRequest#LENS_FILTER_DENSITY
@@ -1807,16 +1954,22 @@
     //
 
     /**
+     * <p>The camera device does not detect any flickering illumination
+     * in the current scene.</p>
      * @see CaptureResult#STATISTICS_SCENE_FLICKER
      */
     public static final int STATISTICS_SCENE_FLICKER_NONE = 0;
 
     /**
+     * <p>The camera device detects illumination flickering at 50Hz
+     * in the current scene.</p>
      * @see CaptureResult#STATISTICS_SCENE_FLICKER
      */
     public static final int STATISTICS_SCENE_FLICKER_50HZ = 1;
 
     /**
+     * <p>The camera device detects illumination flickering at 60Hz
+     * in the current scene.</p>
      * @see CaptureResult#STATISTICS_SCENE_FLICKER
      */
     public static final int STATISTICS_SCENE_FLICKER_60HZ = 2;
@@ -1826,8 +1979,8 @@
     //
 
     /**
-     * <p>The current result is not yet fully synchronized to any request.
-     * Synchronization is in progress, and reading metadata from this
+     * <p>The current result is not yet fully synchronized to any request.</p>
+     * <p>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,
@@ -1842,10 +1995,10 @@
     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>The current result's synchronization status is unknown.</p>
+     * <p>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
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index d4dfdd5..bf7bd37 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -43,14 +43,14 @@
  * <p>CaptureRequests can be created by using a {@link Builder} instance,
  * obtained by calling {@link CameraDevice#createCaptureRequest}</p>
  *
- * <p>CaptureRequests are given to {@link CameraDevice#capture} or
- * {@link CameraDevice#setRepeatingRequest} to capture images from a camera.</p>
+ * <p>CaptureRequests are given to {@link CameraCaptureSession#capture} or
+ * {@link CameraCaptureSession#setRepeatingRequest} to capture images from a camera.</p>
  *
  * <p>Each request can specify a different subset of target Surfaces for the
  * camera to send the captured data to. All the surfaces used in a request must
  * be part of the surface list given to the last call to
- * {@link CameraDevice#configureOutputs}, when the request is submitted to the
- * camera device.</p>
+ * {@link CameraDevice#createCaptureSession}, when the request is submitted to the
+ * session.</p>
  *
  * <p>For example, a request meant for repeating preview might only include the
  * Surface for the preview SurfaceView or SurfaceTexture, while a
@@ -357,11 +357,11 @@
      * request fields to one of the templates defined in {@link CameraDevice}.
      *
      * @see CameraDevice#createCaptureRequest
-     * @see #TEMPLATE_PREVIEW
-     * @see #TEMPLATE_RECORD
-     * @see #TEMPLATE_STILL_CAPTURE
-     * @see #TEMPLATE_VIDEO_SNAPSHOT
-     * @see #TEMPLATE_MANUAL
+     * @see CameraDevice#TEMPLATE_PREVIEW
+     * @see CameraDevice#TEMPLATE_RECORD
+     * @see CameraDevice#TEMPLATE_STILL_CAPTURE
+     * @see CameraDevice#TEMPLATE_VIDEO_SNAPSHOT
+     * @see CameraDevice#TEMPLATE_MANUAL
      */
     public final static class Builder {
 
@@ -381,7 +381,7 @@
          * <p>Add a surface to the list of targets for this request</p>
          *
          * <p>The Surface added must be one of the surfaces included in the most
-         * recent call to {@link CameraDevice#configureOutputs}, when the
+         * recent call to {@link CameraDevice#createCaptureSession}, when the
          * request is given to the camera device.</p>
          *
          * <p>Adding a target more than once has no effect.</p>
@@ -473,7 +473,7 @@
     /**
      * <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
+     * <p>When auto-white balance (AWB) 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
@@ -524,7 +524,7 @@
 
     /**
      * <p>A color transform matrix to use to transform
-     * from sensor RGB color space to output linear sRGB color space</p>
+     * 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
@@ -600,13 +600,17 @@
             new Key<Integer>("android.control.aeAntibandingMode", int.class);
 
     /**
-     * <p>Adjustment to AE target image
-     * brightness</p>
-     * <p>For example, if EV step is 0.333, '6' will mean an
-     * exposure compensation of +2 EV; -3 will mean an exposure
-     * compensation of -1 EV. Note that this control will only be effective
-     * if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF. This control will take effect even when
-     * {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} <code>== true</code>.</p>
+     * <p>Adjustment to auto-exposure (AE) target image
+     * brightness.</p>
+     * <p>The adjustment is measured as a count of steps, with the
+     * step size defined by {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep} and the
+     * allowed range by {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_RANGE android.control.aeCompensationRange}.</p>
+     * <p>For example, if the exposure value (EV) step is 0.333, '6'
+     * will mean an exposure compensation of +2 EV; -3 will mean an
+     * exposure compensation of -1 EV. One EV represents a doubling
+     * of image brightness. Note that this control will only be
+     * effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF. This control
+     * will take effect even when {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} <code>== true</code>.</p>
      * <p>In the event of exposure compensation value being changed, camera device
      * may take several frames to reach the newly requested exposure target.
      * During that time, {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} field will be in the SEARCHING
@@ -614,6 +618,8 @@
      * change from SEARCHING to either CONVERGED, LOCKED (if AE lock is enabled), or
      * FLASH_REQUIRED (if the scene is too dark for still capture).</p>
      *
+     * @see CameraCharacteristics#CONTROL_AE_COMPENSATION_RANGE
+     * @see CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP
      * @see CaptureRequest#CONTROL_AE_LOCK
      * @see CaptureRequest#CONTROL_AE_MODE
      * @see CaptureResult#CONTROL_AE_STATE
@@ -622,7 +628,7 @@
             new Key<Integer>("android.control.aeExposureCompensation", int.class);
 
     /**
-     * <p>Whether AE is currently locked to its latest
+     * <p>Whether auto-exposure (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 /
@@ -711,9 +717,9 @@
 
     /**
      * <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>
+     * maintain exposure.</p>
+     * <p>Only constrains auto-exposure (AE) algorithm, not
+     * manual control of {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}</p>
      *
      * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      */
@@ -727,9 +733,18 @@
      * included at all in the request settings. When included and
      * 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>
+     * <p>The precapture sequence should triggered before starting a
+     * high-quality still capture for final metering decisions to
+     * be made, and for firing pre-capture flash pulses to estimate
+     * scene brightness and required final capture flash power, when
+     * the flash is enabled.</p>
+     * <p>Normally, this entry should be set to START for only a
+     * single request, and the application should wait until the
+     * sequence completes before starting a new one.</p>
+     * <p>The exact effect of auto-exposure (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
@@ -739,8 +754,8 @@
             new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
 
     /**
-     * <p>Whether AF is currently enabled, and what
-     * mode it is set to</p>
+     * <p>Whether auto-focus (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,
@@ -793,7 +808,11 @@
      * 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>
+     * <p>Generally, applications should set this entry to START or CANCEL for only a
+     * single capture, and then return it to IDLE (or not set at all). Specifying
+     * START for multiple captures in a row means restarting the AF operation over
+     * and over again.</p>
+     * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see #CONTROL_AF_TRIGGER_IDLE
@@ -804,31 +823,37 @@
             new Key<Integer>("android.control.afTrigger", int.class);
 
     /**
-     * <p>Whether AWB is currently locked to its
+     * <p>Whether auto-white balance (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>
+     * <p>Note that AWB lock is only meaningful when
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} is in the AUTO mode; in other modes,
+     * AWB is already fixed to a specific setting.</p>
+     *
+     * @see CaptureRequest#CONTROL_AWB_MODE
      */
     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 auto-white balance (AWB) is currently setting the color
      * transform fields, and what its illumination target
      * 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
+     * <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
+     * <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>
+     * <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. The application's values for
+     * {@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} are ignored.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_GAINS
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -879,8 +904,8 @@
      * strategy.</p>
      * <p>This control (except for MANUAL) is only effective if
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
-     * <p>ZERO_SHUTTER_LAG must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains ZSL. MANUAL must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
      * contains MANUAL_SENSOR.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
@@ -955,7 +980,9 @@
      * <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>
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.
+     * The scene modes available for a given camera device are listed in
+     * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}.</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
@@ -963,6 +990,7 @@
      *
      * @see CaptureRequest#CONTROL_AE_MODE
      * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
      * @see CaptureRequest#CONTROL_AWB_MODE
      * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_SCENE_MODE_DISABLED
@@ -988,7 +1016,9 @@
 
     /**
      * <p>Whether video stabilization is
-     * active</p>
+     * active.</p>
+     * <p>Video stabilization automatically translates and scales images from the camera
+     * in order to stabilize motion between consecutive frames.</p>
      * <p>If enabled, video stabilization can modify the
      * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to keep the video stream
      * stabilized</p>
@@ -1030,7 +1060,7 @@
      * <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
+     * control should be used along with auto-exposure (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>
@@ -1102,21 +1132,21 @@
 
     /**
      * <p>Compression quality of the final JPEG
-     * image</p>
-     * <p>85-95 is typical usage range</p>
+     * 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>
+     * 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
@@ -1204,7 +1234,7 @@
 
     /**
      * <p>Distance to plane of sharpest focus,
-     * measured from frontmost surface of the lens</p>
+     * 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
@@ -1222,12 +1252,18 @@
     /**
      * <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>
+     * <p>OIS is used to compensate for motion blur due to small
+     * movements of the camera during capture. Unlike digital image
+     * stabilization ({@link CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE android.control.videoStabilizationMode}), 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>Not all devices will support OIS; see
+     * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
+     * available controls.</p>
+     *
+     * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
      * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
      * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
      */
@@ -1235,16 +1271,15 @@
             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
+     * <p>This must be set to a valid mode from
      * {@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
+     * even if it slows down capture rate. FAST means the camera device will not
      * slow down capture rate when applying noise filtering.</p>
      *
      * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
@@ -1265,40 +1300,39 @@
             new Key<Integer>("android.request.id", int.class);
 
     /**
-     * <p>(x, y, width, height).</p>
-     * <p>A rectangle with the top-level corner of (x,y) and size
-     * (width, height). The region of the sensor that is used for
-     * output. Each stream must use this rectangle to produce its
-     * output, cropping to a smaller region if necessary to
-     * maintain the stream's aspect ratio.</p>
-     * <p>HAL2.x uses only (x, y, width)</p>
-     * <p>The crop region is applied after the RAW to other color space (e.g. YUV)
-     * conversion. Since raw streams (e.g. RAW16) don't have the conversion stage,
-     * it is not croppable. The crop region will be ignored by raw streams.</p>
+     * <p>The region of the sensor to read out for this capture.</p>
+     * <p>The crop region coordinate system is based off
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being the
+     * top-left corner of the sensor active array.</p>
+     * <p>Output streams use this rectangle to produce their output,
+     * cropping to a smaller region if necessary to maintain the
+     * stream's aspect ratio, then scaling the sensor input to
+     * match the output's configured resolution.</p>
+     * <p>The crop region is applied after the RAW to other color
+     * space (e.g. YUV) conversion. Since raw streams
+     * (e.g. RAW16) don't have the conversion stage, they are not
+     * croppable. The crop region will be ignored by raw streams.</p>
      * <p>For non-raw streams, any additional per-stream cropping will
      * 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
+     * ratio, then 4:3 streams will use the exact crop
+     * region. 16:9 streams will further crop vertically
      * (letterbox).</p>
      * <p>Conversely, if the crop region is set to a 16:9, then 4:3
-     * outputs should crop horizontally (pillarbox), and 16:9
-     * streams should match exactly. These additional crops must
+     * outputs will crop horizontally (pillarbox), and 16:9
+     * streams will match exactly. These additional crops will
      * be centered within the crop region.</p>
-     * <p>The output streams must maintain square pixels at all
-     * times, no matter what the relative aspect ratios of the
-     * crop region and the stream are.  Negative values for
-     * corner are allowed for raw output if full pixel array is
-     * larger than active pixel array. Width and height may be
-     * rounded to nearest larger supportable width, especially
-     * for raw output, where only a few fixed scales may be
-     * possible. The width and height of the crop region cannot
-     * be set to be smaller than floor( activeArraySize.width /
-     * {@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>
+     * <p>The width and height of the crop region cannot
+     * be set to be smaller than
+     * <code>floor( activeArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code> and
+     * <code>floor( activeArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>, respectively.</p>
+     * <p>The camera device may adjust the crop region to account
+     * for rounding and other hardware requirements; the final
+     * crop region used will be included in the output capture
+     * result.</p>
      *
      * @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
             new Key<android.graphics.Rect>("android.scaler.cropRegion", android.graphics.Rect.class);
@@ -1391,12 +1425,20 @@
             new Key<Long>("android.sensor.frameDuration", long.class);
 
     /**
-     * <p>Gain applied to image data. Must be
-     * implemented through analog gain only if set to values
-     * below 'maximum analog sensitivity'.</p>
-     * <p>If the sensor can't apply this exact gain, it should lessen the
-     * gain to the nearest possible value (rather than gain more).</p>
-     * <p>ISO 12232:2006 REI method</p>
+     * <p>The amount of gain applied to sensor data
+     * before processing.</p>
+     * <p>The sensitivity is the standard ISO sensitivity value,
+     * as defined in ISO 12232:2006.</p>
+     * <p>The sensitivity must be within {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}, and
+     * if if it less than {@link CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY android.sensor.maxAnalogSensitivity}, the camera device
+     * is guaranteed to use only analog amplification for applying the gain.</p>
+     * <p>If the camera device cannot apply the exact sensitivity
+     * requested, it will reduce the gain to the nearest supported
+     * value. The final sensitivity used will be available in the
+     * output capture result.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
+     * @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
      */
     public static final Key<Integer> SENSOR_SENSITIVITY =
             new Key<Integer>("android.sensor.sensitivity", int.class);
@@ -1421,7 +1463,7 @@
      * <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
+     * by android.sensor.* will 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
@@ -1459,7 +1501,7 @@
      * lens shading map data in android.statistics.lensShadingMap, with size specified
      * by android.lens.info.shadingMapSize; the returned shading map data will be the one
      * applied by the camera device for this capture request.</p>
-     * <p>The shading map data may depend on the AE and AWB statistics, therefore the reliability
+     * <p>The shading map data may depend on the auto-exposure (AE) and AWB statistics, therefore the reliability
      * of the map data may be affected by the AE and AWB algorithms. When AE and AWB are in
      * AUTO modes({@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF and {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} <code>!=</code> OFF),
      * to get best results, it is recommended that the applications wait for the AE and AWB to
@@ -1476,8 +1518,8 @@
             new Key<Integer>("android.shading.mode", int.class);
 
     /**
-     * <p>State of the face detector
-     * unit</p>
+     * <p>Control for 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
@@ -1494,7 +1536,7 @@
     /**
      * <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>
+     * If set to OFF, no hotpixel map will 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
@@ -1507,7 +1549,7 @@
      * <p>Whether the camera device will output the lens
      * shading map in output result metadata.</p>
      * <p>When set to ON,
-     * android.statistics.lensShadingMap must be provided in
+     * android.statistics.lensShadingMap will be provided in
      * the output result metadata.</p>
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 7d07c92..3d17ed3 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -319,7 +319,7 @@
     /**
      * <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
+     * <p>When auto-white balance (AWB) 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
@@ -370,7 +370,7 @@
 
     /**
      * <p>A color transform matrix to use to transform
-     * from sensor RGB color space to output linear sRGB color space</p>
+     * 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
@@ -446,13 +446,17 @@
             new Key<Integer>("android.control.aeAntibandingMode", int.class);
 
     /**
-     * <p>Adjustment to AE target image
-     * brightness</p>
-     * <p>For example, if EV step is 0.333, '6' will mean an
-     * exposure compensation of +2 EV; -3 will mean an exposure
-     * compensation of -1 EV. Note that this control will only be effective
-     * if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF. This control will take effect even when
-     * {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} <code>== true</code>.</p>
+     * <p>Adjustment to auto-exposure (AE) target image
+     * brightness.</p>
+     * <p>The adjustment is measured as a count of steps, with the
+     * step size defined by {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep} and the
+     * allowed range by {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_RANGE android.control.aeCompensationRange}.</p>
+     * <p>For example, if the exposure value (EV) step is 0.333, '6'
+     * will mean an exposure compensation of +2 EV; -3 will mean an
+     * exposure compensation of -1 EV. One EV represents a doubling
+     * of image brightness. Note that this control will only be
+     * effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF. This control
+     * will take effect even when {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} <code>== true</code>.</p>
      * <p>In the event of exposure compensation value being changed, camera device
      * may take several frames to reach the newly requested exposure target.
      * During that time, {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} field will be in the SEARCHING
@@ -460,6 +464,8 @@
      * change from SEARCHING to either CONVERGED, LOCKED (if AE lock is enabled), or
      * FLASH_REQUIRED (if the scene is too dark for still capture).</p>
      *
+     * @see CameraCharacteristics#CONTROL_AE_COMPENSATION_RANGE
+     * @see CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP
      * @see CaptureRequest#CONTROL_AE_LOCK
      * @see CaptureRequest#CONTROL_AE_MODE
      * @see CaptureResult#CONTROL_AE_STATE
@@ -468,7 +474,7 @@
             new Key<Integer>("android.control.aeExposureCompensation", int.class);
 
     /**
-     * <p>Whether AE is currently locked to its latest
+     * <p>Whether auto-exposure (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 /
@@ -557,9 +563,9 @@
 
     /**
      * <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>
+     * maintain exposure.</p>
+     * <p>Only constrains auto-exposure (AE) algorithm, not
+     * manual control of {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}</p>
      *
      * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      */
@@ -573,9 +579,18 @@
      * included at all in the request settings. When included and
      * 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>
+     * <p>The precapture sequence should triggered before starting a
+     * high-quality still capture for final metering decisions to
+     * be made, and for firing pre-capture flash pulses to estimate
+     * scene brightness and required final capture flash power, when
+     * the flash is enabled.</p>
+     * <p>Normally, this entry should be set to START for only a
+     * single request, and the application should wait until the
+     * sequence completes before starting a new one.</p>
+     * <p>The exact effect of auto-exposure (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
@@ -585,7 +600,7 @@
             new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
 
     /**
-     * <p>Current state of AE algorithm</p>
+     * <p>Current state of the auto-exposure (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
@@ -783,8 +798,8 @@
             new Key<Integer>("android.control.aeState", int.class);
 
     /**
-     * <p>Whether AF is currently enabled, and what
-     * mode it is set to</p>
+     * <p>Whether auto-focus (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,
@@ -837,7 +852,11 @@
      * 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>
+     * <p>Generally, applications should set this entry to START or CANCEL for only a
+     * single capture, and then return it to IDLE (or not set at all). Specifying
+     * START for multiple captures in a row means restarting the AF operation over
+     * and over again.</p>
+     * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see #CONTROL_AF_TRIGGER_IDLE
@@ -848,7 +867,7 @@
             new Key<Integer>("android.control.afTrigger", int.class);
 
     /**
-     * <p>Current state of AF algorithm.</p>
+     * <p>Current state of auto-focus (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
@@ -1027,13 +1046,13 @@
      * <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>
+     * <td align="center">Immediate transition, 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>
+     * <td align="center">Immediate transition, if focus is bad. Lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">PASSIVE_SCAN</td>
@@ -1057,13 +1076,13 @@
      * <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>
+     * <td align="center">Immediate transition, 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>
+     * <td align="center">Immediate transition, lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">FOCUSED_LOCKED</td>
@@ -1130,13 +1149,13 @@
      * <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>
+     * <td align="center">Eventual transition once the 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">Eventual trans. if cannot focus, Lens now locked</td>
+     * <td align="center">Eventual transition if cannot find focus. Lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">PASSIVE_SCAN</td>
@@ -1245,31 +1264,37 @@
             new Key<Integer>("android.control.afState", int.class);
 
     /**
-     * <p>Whether AWB is currently locked to its
+     * <p>Whether auto-white balance (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>
+     * <p>Note that AWB lock is only meaningful when
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} is in the AUTO mode; in other modes,
+     * AWB is already fixed to a specific setting.</p>
+     *
+     * @see CaptureRequest#CONTROL_AWB_MODE
      */
     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 auto-white balance (AWB) is currently setting the color
      * transform fields, and what its illumination target
      * 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
+     * <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
+     * <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>
+     * <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. The application's values for
+     * {@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} are ignored.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_GAINS
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -1320,8 +1345,8 @@
      * strategy.</p>
      * <p>This control (except for MANUAL) is only effective if
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
-     * <p>ZERO_SHUTTER_LAG must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains ZSL. MANUAL must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
      * contains MANUAL_SENSOR.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
@@ -1338,7 +1363,7 @@
             new Key<Integer>("android.control.captureIntent", int.class);
 
     /**
-     * <p>Current state of AWB algorithm</p>
+     * <p>Current state of auto-white balance (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
@@ -1526,7 +1551,9 @@
      * <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>
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.
+     * The scene modes available for a given camera device are listed in
+     * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}.</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
@@ -1534,6 +1561,7 @@
      *
      * @see CaptureRequest#CONTROL_AE_MODE
      * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
      * @see CaptureRequest#CONTROL_AWB_MODE
      * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_SCENE_MODE_DISABLED
@@ -1559,7 +1587,9 @@
 
     /**
      * <p>Whether video stabilization is
-     * active</p>
+     * active.</p>
+     * <p>Video stabilization automatically translates and scales images from the camera
+     * in order to stabilize motion between consecutive frames.</p>
      * <p>If enabled, video stabilization can modify the
      * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to keep the video stream
      * stabilized</p>
@@ -1601,7 +1631,7 @@
      * <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
+     * control should be used along with auto-exposure (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>
@@ -1690,21 +1720,21 @@
 
     /**
      * <p>Compression quality of the final JPEG
-     * image</p>
-     * <p>85-95 is typical usage range</p>
+     * 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>
+     * 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
@@ -1792,7 +1822,7 @@
 
     /**
      * <p>Distance to plane of sharpest focus,
-     * measured from frontmost surface of the lens</p>
+     * 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 =
@@ -1800,7 +1830,7 @@
 
     /**
      * <p>The range of scene distances that are in
-     * sharp focus (depth of field)</p>
+     * sharp focus (depth of field).</p>
      * <p>If variable focus not supported, can still report
      * fixed depth of field range</p>
      */
@@ -1810,12 +1840,18 @@
     /**
      * <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>
+     * <p>OIS is used to compensate for motion blur due to small
+     * movements of the camera during capture. Unlike digital image
+     * stabilization ({@link CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE android.control.videoStabilizationMode}), 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>Not all devices will support OIS; see
+     * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
+     * available controls.</p>
+     *
+     * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
      * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
      * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
      */
@@ -1859,16 +1895,15 @@
             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
+     * <p>This must be set to a valid mode from
      * {@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
+     * even if it slows down capture rate. FAST means the camera device will not
      * slow down capture rate when applying noise filtering.</p>
      *
      * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
@@ -1934,40 +1969,39 @@
             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>The crop region is applied after the RAW to other color space (e.g. YUV)
-     * conversion. Since raw streams (e.g. RAW16) don't have the conversion stage,
-     * it is not croppable. The crop region will be ignored by raw streams.</p>
+     * <p>The region of the sensor to read out for this capture.</p>
+     * <p>The crop region coordinate system is based off
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with <code>(0, 0)</code> being the
+     * top-left corner of the sensor active array.</p>
+     * <p>Output streams use this rectangle to produce their output,
+     * cropping to a smaller region if necessary to maintain the
+     * stream's aspect ratio, then scaling the sensor input to
+     * match the output's configured resolution.</p>
+     * <p>The crop region is applied after the RAW to other color
+     * space (e.g. YUV) conversion. Since raw streams
+     * (e.g. RAW16) don't have the conversion stage, they are not
+     * croppable. The crop region will be ignored by raw streams.</p>
      * <p>For non-raw streams, any additional per-stream cropping will
      * 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
+     * ratio, then 4:3 streams will use the exact crop
+     * region. 16:9 streams will further crop vertically
      * (letterbox).</p>
      * <p>Conversely, if the crop region is set to a 16:9, then 4:3
-     * outputs should crop horizontally (pillarbox), and 16:9
-     * streams should match exactly. These additional crops must
+     * outputs will crop horizontally (pillarbox), and 16:9
+     * streams will match exactly. These additional crops will
      * be centered within the crop region.</p>
-     * <p>The output streams must maintain square pixels at all
-     * times, no matter what the relative aspect ratios of the
-     * crop region and the stream are.  Negative values for
-     * corner are allowed for raw output if full pixel array is
-     * larger than active pixel array. Width and height may be
-     * rounded to nearest larger supportable width, especially
-     * for raw output, where only a few fixed scales may be
-     * possible. The width and height of the crop region cannot
-     * be set to be smaller than floor( activeArraySize.width /
-     * {@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>
+     * <p>The width and height of the crop region cannot
+     * be set to be smaller than
+     * <code>floor( activeArraySize.width / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code> and
+     * <code>floor( activeArraySize.height / {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} )</code>, respectively.</p>
+     * <p>The camera device may adjust the crop region to account
+     * for rounding and other hardware requirements; the final
+     * crop region used will be included in the output capture
+     * result.</p>
      *
      * @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
             new Key<android.graphics.Rect>("android.scaler.cropRegion", android.graphics.Rect.class);
@@ -2060,21 +2094,35 @@
             new Key<Long>("android.sensor.frameDuration", long.class);
 
     /**
-     * <p>Gain applied to image data. Must be
-     * implemented through analog gain only if set to values
-     * below 'maximum analog sensitivity'.</p>
-     * <p>If the sensor can't apply this exact gain, it should lessen the
-     * gain to the nearest possible value (rather than gain more).</p>
-     * <p>ISO 12232:2006 REI method</p>
+     * <p>The amount of gain applied to sensor data
+     * before processing.</p>
+     * <p>The sensitivity is the standard ISO sensitivity value,
+     * as defined in ISO 12232:2006.</p>
+     * <p>The sensitivity must be within {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}, and
+     * if if it less than {@link CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY android.sensor.maxAnalogSensitivity}, the camera device
+     * is guaranteed to use only analog amplification for applying the gain.</p>
+     * <p>If the camera device cannot apply the exact sensitivity
+     * requested, it will reduce the gain to the nearest supported
+     * value. The final sensitivity used will be available in the
+     * output capture result.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
+     * @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
      */
     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>
+     * row of the image sensor, in nanoseconds.</p>
+     * <p>The timestamps are also included in all image
+     * buffers produced for the same capture, and will be identical
+     * on all the outputs. The timestamps measure time since an
+     * unspecified starting point, and are monotonically
+     * increasing.</p>
+     * <p>They can be compared with the timestamps for other captures
+     * from the same camera device, but are not guaranteed to be
+     * comparable to any other time source.</p>
      */
     public static final Key<Long> SENSOR_TIMESTAMP =
             new Key<Long>("android.sensor.timestamp", long.class);
@@ -2150,7 +2198,7 @@
      * <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
+     * by android.sensor.* will 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
@@ -2188,7 +2236,7 @@
      * lens shading map data in android.statistics.lensShadingMap, with size specified
      * by android.lens.info.shadingMapSize; the returned shading map data will be the one
      * applied by the camera device for this capture request.</p>
-     * <p>The shading map data may depend on the AE and AWB statistics, therefore the reliability
+     * <p>The shading map data may depend on the auto-exposure (AE) and AWB statistics, therefore the reliability
      * of the map data may be affected by the AE and AWB algorithms. When AE and AWB are in
      * AUTO modes({@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF and {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} <code>!=</code> OFF),
      * to get best results, it is recommended that the applications wait for the AE and AWB to
@@ -2205,8 +2253,8 @@
             new Key<Integer>("android.shading.mode", int.class);
 
     /**
-     * <p>State of the face detector
-     * unit</p>
+     * <p>Control for 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
@@ -2221,9 +2269,13 @@
             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>Each detected face is given a unique ID that is valid for as long as the face is visible
+     * to the camera device.  A face that leaves the field of view and later returns may be
+     * assigned a new ID.</p>
+     * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL</p>
+     *
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<int[]> STATISTICS_FACE_IDS =
@@ -2231,8 +2283,13 @@
 
     /**
      * <p>List of landmarks for detected
-     * faces</p>
-     * <p>Only available if faceDetectMode == FULL</p>
+     * faces.</p>
+     * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+     * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+     * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<int[]> STATISTICS_FACE_LANDMARKS =
@@ -2240,8 +2297,13 @@
 
     /**
      * <p>List of the bounding rectangles for detected
-     * faces</p>
-     * <p>Only available if faceDetectMode != OFF</p>
+     * faces.</p>
+     * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+     * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+     * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<android.graphics.Rect[]> STATISTICS_FACE_RECTANGLES =
@@ -2250,8 +2312,9 @@
     /**
      * <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>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF.</p>
+     *
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<byte[]> STATISTICS_FACE_SCORES =
@@ -2370,7 +2433,7 @@
      * 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,
+     * <p>This value should always be calculated by the auto-white balance (AWB) block,
      * regardless of the android.control.* current values.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
@@ -2396,7 +2459,7 @@
      * 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,
+     * <p>This value should always be calculated by the auto-white balance (AWB) block,
      * regardless of the android.control.* current values.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      * @deprecated
@@ -2415,12 +2478,13 @@
      * 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>
+     * (<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 perform
+     * 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>Reports NONE if there doesn't appear to be flickering illumination.</p>
      *
      * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
      * @see CaptureRequest#CONTROL_AE_MODE
@@ -2435,7 +2499,7 @@
     /**
      * <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>
+     * If set to OFF, no hotpixel map will 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
@@ -2463,7 +2527,7 @@
      * <p>Whether the camera device will output the lens
      * shading map in output result metadata.</p>
      * <p>When set to ON,
-     * android.statistics.lensShadingMap must be provided in
+     * android.statistics.lensShadingMap will be provided in
      * the output result metadata.</p>
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
diff --git a/core/java/android/hardware/camera2/package.html b/core/java/android/hardware/camera2/package.html
index 9f6c2a9..ef0d7bd 100644
--- a/core/java/android/hardware/camera2/package.html
+++ b/core/java/android/hardware/camera2/package.html
@@ -34,49 +34,71 @@
 CameraDevices} provide a set of static property information that
 describes the hardware device and the available settings and output
 parameters for the device. This information is provided through the
-{@link android.hardware.camera2.CameraCharacteristics} object.</p>
+{@link android.hardware.camera2.CameraCharacteristics} object, and is
+available through {@link
+android.hardware.camera2.CameraManager#getCameraCharacteristics}</p>
 
 <p>To capture or stream images from a camera device, the application
-must first configure a set of output Surfaces for use with the camera
-device, with {@link
-android.hardware.camera2.CameraDevice#configureOutputs}. Each
-Surface has to be pre-configured with an appropriate size and format
-(if applicable) to match the sizes and formats available from the
-camera device. A target Surface can be obtained from a variety of
-classes, including {@link android.view.SurfaceView}, {@link
-android.graphics.SurfaceTexture} via {@link
-android.view.Surface#Surface(SurfaceTexture), {@link
-android.media.MediaCodec}, and {@link android.media.ImageReader}.
+must first create a {@link
+android.hardware.camera2.CameraCaptureSession camera capture session}
+with a set of output Surfaces for use with the camera device, with
+{@link
+android.hardware.camera2.CameraDevice#createCaptureSession}. Each
+Surface has to be pre-configured with an {@link
+android.hardware.camera2.params.StreamConfigurationMap appropriate
+size and format} (if applicable) to match the sizes and formats
+available from the camera device. A target Surface can be obtained
+from a variety of classes, including {@link android.view.SurfaceView},
+{@link android.graphics.SurfaceTexture} via
+{@link android.view.Surface#Surface(SurfaceTexture)},
+{@link android.media.MediaCodec}, {@link android.media.MediaRecorder},
+{@link android.renderscript.Allocation}, and {@link android.media.ImageReader}.
 </p>
 
+<p>Generally, camera preview images are sent to {@link
+android.view.SurfaceView} or {@link android.view.TextureView} (via its
+{@link android.graphics.SurfaceTexture}). Capture of JPEG images or
+RAW buffers for {@link android.hardware.camera2.DngCreator} can be done
+with {@link android.media.ImageReader} with the
+{android.graphics.ImageFormat#JPEG} and
+{android.graphics.ImageFormat#RAW_SENSOR} formats.  Application-driven
+processing of camera data in RenderScript, OpenGL ES, or directly in
+managed or native code is best done through {@link
+android.renderscript.Allocation} with a YUV {@link
+android.renderscript.Type}, {@link android.graphics.SurfaceTexture},
+and {@link android.media.ImageReader} with a
+{android.graphics.ImageFormat#YUV_420_888} format, respectively.</p>
+
 <p>The application then needs to construct a {@link
 android.hardware.camera2.CaptureRequest}, which defines all the
 capture parameters needed by a camera device to capture a single
 image. The request also lists which of the configured output Surfaces
 should be used as targets for this capture. The CameraDevice has a
 {@link android.hardware.camera2.CameraDevice#createCaptureRequest
-convenience factory method} for creating a request for a given use
-case which is optimized for the Android device the application is
-running on.</p>
+factory method} for creating a {@link
+android.hardware.camera2.CaptureRequest.Builder request builder} for a
+given use case, which is optimized for the Android device the
+application is running on.</p>
 
-<p>Once the request has been set up, it can be handed to the
-CameraDevice either for a one-shot {@link
-android.hardware.camera2.CameraDevice#capture} or for an endlessly
-{@link android.hardware.camera2.CameraDevice#setRepeatingRequest
-repeating} use. Both methods also accept a list of requests to use as
-a burst capture / repeating burst. Repeating requests have a lower
-priority than captures, so a request submitted
+<p>Once the request has been set up, it can be handed to the active
+capture session either for a one-shot {@link
+android.hardware.camera2.CameraCaptureSession#capture capture} or for
+an endlessly {@link
+android.hardware.camera2.CameraCaptureSession#setRepeatingRequest
+repeating} use. Both methods also have a variant that accepts a list
+of requests to use as a burst capture / repeating burst. Repeating
+requests have a lower priority than captures, so a request submitted
 through <code>capture()</code> while there's a repeating request
-configured will be captured as soon as the current repeat (burst)
-capture completes.</p>
+configured will be captured before any new instances of the currently
+repeating (burst) capture will begin capture.</p>
 
 <p>After processing a request, the camera device will produce a {@link
-android.hardware.camera2.CaptureResult} object, which contains
+android.hardware.camera2.TotalCaptureResult} object, which contains
 information about the state of the camera device at time of capture,
 and the final settings used. These may vary somewhat from the request,
 if rounding or resolving contradictory parameters was necessary. The
 camera device will also send a frame of image data into each of the
-output streams included in the request. These are produced
+output {@code Surfaces} included in the request. These are produced
 asynchronously relative to the output CaptureResult, sometimes
 substantially later.</p>
 
diff --git a/core/java/android/hardware/camera2/params/StreamConfiguration.java b/core/java/android/hardware/camera2/params/StreamConfiguration.java
index 1c6b6e9..a6fc10f 100644
--- a/core/java/android/hardware/camera2/params/StreamConfiguration.java
+++ b/core/java/android/hardware/camera2/params/StreamConfiguration.java
@@ -28,8 +28,9 @@
 
 /**
  * Immutable class to store the available stream
- * {@link CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS configurations} to be used
- * when configuring streams with {@link CameraDevice#configureOutputs}.
+ * {@link CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS configurations} to set up
+ * {@link android.view.Surface Surfaces} for creating a {@link CameraCaptureSession capture session}
+ * with {@link CameraDevice#createCaptureSession}.
  * <!-- TODO: link to input stream configuration -->
  *
  * <p>This is the authoritative list for all input/output formats (and sizes respectively
@@ -124,7 +125,7 @@
      *
      * @return {@code true} if output configuration, {@code false} otherwise
      *
-     * @see CameraDevice#configureOutputs
+     * @see CameraDevice#createCaptureSession
      */
     public boolean isOutput() {
         return !mInput;
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 4cd6d151..3036425 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -34,8 +34,10 @@
 
 /**
  * Immutable class to store the available stream
- * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP configurations} to be used
- * when configuring streams with {@link CameraDevice#configureOutputs}.
+ * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP configurations} to set up
+ * {@link android.view.Surface Surfaces} for creating a
+ * {@link android.hardware.camera2.CameraCaptureSession capture session} with
+ * {@link android.hardware.camera2.CameraDevice#createCaptureSession}.
  * <!-- TODO: link to input stream configuration -->
  *
  * <p>This is the authoritative list for all <!-- input/ -->output formats (and sizes respectively
@@ -56,7 +58,7 @@
  * }</code></pre>
  *
  * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
- * @see CameraDevice#configureOutputs
+ * @see CameraDevice#createCaptureSession
  */
 public final class StreamConfigurationMap {
 
@@ -155,8 +157,8 @@
     }
 
     /**
-     * Determine whether or not output streams can be
-     * {@link CameraDevice#configureOutputs configured} with a particular user-defined format.
+     * Determine whether or not output surfaces with a particular user-defined format can be passed
+     * {@link CameraDevice#createCaptureSession createCaptureSession}.
      *
      * <p>This method determines that the output {@code format} is supported by the camera device;
      * each output {@code surface} target may or may not itself support that {@code format}.
@@ -168,7 +170,7 @@
      * @param format an image format from either {@link ImageFormat} or {@link PixelFormat}
      * @return
      *          {@code true} iff using a {@code surface} with this {@code format} will be
-     *          supported with {@link CameraDevice#configureOutputs}
+     *          supported with {@link CameraDevice#createCaptureSession}
      *
      * @throws IllegalArgumentException
      *          if the image format was not a defined named constant
@@ -176,7 +178,7 @@
      *
      * @see ImageFormat
      * @see PixelFormat
-     * @see CameraDevice#configureOutputs
+     * @see CameraDevice#createCaptureSession
      */
     public boolean isOutputSupportedFor(int format) {
         checkArgumentFormat(format);
@@ -210,7 +212,7 @@
      *
      * <p>Generally speaking this means that creating a {@link Surface} from that class <i>may</i>
      * provide a producer endpoint that is suitable to be used with
-     * {@link CameraDevice#configureOutputs}.</p>
+     * {@link CameraDevice#createCaptureSession}.</p>
      *
      * <p>Since not all of the above classes support output of all format and size combinations,
      * the particular combination should be queried with {@link #isOutputSupportedFor(Surface)}.</p>
@@ -220,7 +222,7 @@
      *
      * @throws NullPointerException if {@code klass} was {@code null}
      *
-     * @see CameraDevice#configureOutputs
+     * @see CameraDevice#createCaptureSession
      * @see #isOutputSupportedFor(Surface)
      */
     public static <T> boolean isOutputSupportedFor(Class<T> klass) {
@@ -244,8 +246,8 @@
     }
 
     /**
-     * Determine whether or not the {@code surface} in its current state is suitable to be
-     * {@link CameraDevice#configureOutputs configured} as an output.
+     * Determine whether or not the {@code surface} in its current state is suitable to be included
+     * in a {@link CameraDevice#createCaptureSession capture session} as an output.
      *
      * <p>Not all surfaces are usable with the {@link CameraDevice}, and not all configurations
      * of that {@code surface} are compatible. Some classes that provide the {@code surface} are
@@ -269,7 +271,7 @@
      *
      * @throws NullPointerException if {@code surface} was {@code null}
      *
-     * @see CameraDevice#configureOutputs
+     * @see CameraDevice#createCaptureSession
      * @see #isOutputSupportedFor(Class)
      */
     public boolean isOutputSupportedFor(Surface surface) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index b96f166..7faf8ef 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -22,6 +22,7 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.net.NetworkUtils;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
 import android.os.Handler;
@@ -428,6 +429,11 @@
      */
     public final static int INVALID_NET_ID = 0;
 
+    /**
+     * @hide
+     */
+    public final static int REQUEST_ID_UNSET = 0;
+
     private final IConnectivityManager mService;
 
     private final String mPackageName;
@@ -862,10 +868,10 @@
             return -1;
         }
 
-        NetworkRequest request = removeRequestForFeature(netCap);
-        if (request != null) {
+        NetworkCallback networkCallback = removeRequestForFeature(netCap);
+        if (networkCallback != null) {
             Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
-            releaseNetworkRequest(request);
+            unregisterNetworkCallback(networkCallback);
         }
         return 1;
     }
@@ -882,8 +888,8 @@
      * @hide
      */
     public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
-        for (Integer capability : nc.getNetworkCapabilities()) {
-            switch (capability.intValue()) {
+        for (int capability : nc.getCapabilities()) {
+            switch (capability) {
                 case NetworkCapabilities.NET_CAPABILITY_CBS:
                 case NetworkCapabilities.NET_CAPABILITY_DUN:
                 case NetworkCapabilities.NET_CAPABILITY_EIMS:
@@ -901,7 +907,7 @@
         }
         // All the capabilities are typically provided by restricted networks.
         // Conclude that this network is restricted.
-        nc.removeNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
     }
 
     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
@@ -925,15 +931,14 @@
                 return null;
             }
             NetworkCapabilities netCap = new NetworkCapabilities();
-            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-            netCap.addNetworkCapability(cap);
+            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
             maybeMarkCapabilitiesRestricted(netCap);
             return netCap;
         } else if (networkType == TYPE_WIFI) {
             if ("p2p".equals(feature)) {
                 NetworkCapabilities netCap = new NetworkCapabilities();
                 netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
-                netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
+                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
                 maybeMarkCapabilitiesRestricted(netCap);
                 return netCap;
             }
@@ -976,18 +981,18 @@
         int expireSequenceNumber;
         Network currentNetwork;
         int delay = -1;
-        NetworkCallbackListener networkCallbackListener = new NetworkCallbackListener() {
+        NetworkCallback networkCallback = new NetworkCallback() {
             @Override
-            public void onAvailable(NetworkRequest request, Network network) {
+            public void onAvailable(Network network) {
                 currentNetwork = network;
                 Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
-                network.bindProcessForHostResolution();
+                setProcessDefaultNetworkForHostResolution(network);
             }
             @Override
-            public void onLost(NetworkRequest request, Network network) {
+            public void onLost(Network network) {
                 if (network.equals(currentNetwork)) {
                     currentNetwork = null;
-                    network.unbindProcessForHostResolution();
+                    setProcessDefaultNetworkForHostResolution(null);
                 }
                 Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
             }
@@ -1018,7 +1023,7 @@
             if (l == null) return;
             ourSeqNum = l.expireSequenceNumber;
             if (l.expireSequenceNumber == sequenceNum) {
-                releaseNetworkRequest(l.networkRequest);
+                unregisterNetworkCallback(l.networkCallback);
                 sLegacyRequests.remove(netCap);
             }
         }
@@ -1035,7 +1040,7 @@
         l.networkCapabilities = netCap;
         l.delay = delay;
         l.expireSequenceNumber = 0;
-        l.networkRequest = sendRequestForNetwork(netCap, l.networkCallbackListener, 0,
+        l.networkRequest = sendRequestForNetwork(netCap, l.networkCallback, 0,
                 REQUEST, type);
         if (l.networkRequest == null) return null;
         sLegacyRequests.put(netCap, l);
@@ -1051,11 +1056,11 @@
         }
     }
 
-    private NetworkRequest removeRequestForFeature(NetworkCapabilities netCap) {
+    private NetworkCallback removeRequestForFeature(NetworkCapabilities netCap) {
         synchronized (sLegacyRequests) {
             LegacyRequest l = sLegacyRequests.remove(netCap);
             if (l == null) return null;
-            return l.networkRequest;
+            return l.networkCallback;
         }
     }
 
@@ -1071,7 +1076,7 @@
      * @return {@code true} on success, {@code false} on failure
      *
      * @deprecated Deprecated in favor of the {@link #requestNetwork},
-     *             {@link Network#bindProcess} and {@link Network#socketFactory} api.
+     *             {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api.
      */
     public boolean requestRouteToHost(int networkType, int hostAddress) {
         InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
@@ -1095,7 +1100,7 @@
      * @return {@code true} on success, {@code false} on failure
      * @hide
      * @deprecated Deprecated in favor of the {@link #requestNetwork} and
-     *             {@link Network#bindProcess} api.
+     *             {@link #setProcessDefaultNetwork} api.
      */
     public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
         byte[] address = hostAddress.getAddress();
@@ -1178,8 +1183,8 @@
     }
 
     /**
-     * Callback for use with {@link ConnectivityManager#registerNetworkActiveListener} to
-     * find out when the current network has gone in to a high power state.
+     * Callback for use with {@link ConnectivityManager#registerDefaultNetworkActiveListener}
+     * to find out when the system default network has gone in to a high power state.
      */
     public interface OnNetworkActiveListener {
         /**
@@ -1188,7 +1193,7 @@
          * 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}.
+         * {@link ConnectivityManager#isDefaultNetworkActive}.
          */
         public void onNetworkActive();
     }
@@ -1209,13 +1214,18 @@
                     = 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.
+     * Start listening to reports when the system's default data network is active, meaning it is
+     * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
+     * to determine the current state of the system's default network after registering the
+     * listener.
+     * <p>
+     * If the process default network has been set with
+     * {@link ConnectivityManager#setProcessDefaultNetwork} this function will not
+     * reflect the process's default, but the system default.
      *
      * @param l The listener to be told when the network is active.
      */
-    public void registerNetworkActiveListener(final OnNetworkActiveListener l) {
+    public void registerDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
         INetworkActivityListener rl = new INetworkActivityListener.Stub() {
             @Override
             public void onNetworkActive() throws RemoteException {
@@ -1232,11 +1242,11 @@
 
     /**
      * Remove network active listener previously registered with
-     * {@link #registerNetworkActiveListener}.
+     * {@link #registerDefaultNetworkActiveListener}.
      *
      * @param l Previously registered listener.
      */
-    public void unregisterNetworkActiveListener(OnNetworkActiveListener l) {
+    public void unregisterDefaultNetworkActiveListener(OnNetworkActiveListener l) {
         INetworkActivityListener rl = mNetworkActivityListeners.get(l);
         if (rl == null) {
             throw new IllegalArgumentException("Listener not registered: " + l);
@@ -1255,7 +1265,7 @@
      * 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() {
+    public boolean isDefaultNetworkActive() {
         try {
             return getNetworkManagementService().isNetworkActive();
         } catch (RemoteException e) {
@@ -1887,7 +1897,7 @@
      * Base class for NetworkRequest callbacks.  Used for notifications about network
      * changes.  Should be extended by applications wanting notifications.
      */
-    public static class NetworkCallbackListener {
+    public static class NetworkCallback {
         /** @hide */
         public static final int PRECHECK     = 1;
         /** @hide */
@@ -1910,78 +1920,68 @@
          * Called whenever the framework connects to a network that it may use to
          * satisfy this request
          */
-        public void onPreCheck(NetworkRequest networkRequest, Network network) {}
+        public void onPreCheck(Network network) {}
 
         /**
          * Called when the framework connects and has declared new network ready for use.
+         * This callback may be called more than once if the {@link Network} that is
+         * satisfying the request changes.
          *
-         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
          * @param network The {@link Network} of the satisfying network.
          */
-        public void onAvailable(NetworkRequest networkRequest, Network network) {}
+        public void onAvailable(Network network) {}
 
         /**
          * Called when the network is about to be disconnected.  Often paired with an
-         * {@link NetworkCallbackListener#onAvailable} call with the new replacement network
+         * {@link NetworkCallback#onAvailable} call with the new replacement network
          * for graceful handover.  This may not be called if we have a hard loss
          * (loss without warning).  This may be followed by either a
-         * {@link NetworkCallbackListener#onLost} call or a
-         * {@link NetworkCallbackListener#onAvailable} call for this network depending
+         * {@link NetworkCallback#onLost} call or a
+         * {@link NetworkCallback#onAvailable} call for this network depending
          * on whether we lose or regain it.
          *
-         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
-         * @param network The {@link Network} of the failing network.
-         * @param maxSecToLive The time in seconds the framework will attempt to keep the
-         *                     network connected.  Note that the network may suffers a
+         * @param network The {@link Network} that is about to be disconnected.
+         * @param maxMsToLive The time in ms the framework will attempt to keep the
+         *                     network connected.  Note that the network may suffer a
          *                     hard loss at any time.
          */
-        public void onLosing(NetworkRequest networkRequest, Network network, int maxSecToLive) {}
+        public void onLosing(Network network, int maxMsToLive) {}
 
         /**
          * Called when the framework has a hard loss of the network or when the
          * graceful failure ends.
          *
-         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
          * @param network The {@link Network} lost.
          */
-        public void onLost(NetworkRequest networkRequest, Network network) {}
+        public void onLost(Network network) {}
 
         /**
          * Called if no network is found in the given timeout time.  If no timeout is given,
          * this will not be called.
          * @hide
          */
-        public void onUnavailable(NetworkRequest networkRequest) {}
+        public void onUnavailable() {}
 
         /**
          * Called when the network the framework connected to for this request
          * changes capabilities but still satisfies the stated need.
          *
-         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
          * @param network The {@link Network} whose capabilities have changed.
          * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
          */
-        public void onNetworkCapabilitiesChanged(NetworkRequest networkRequest, Network network,
+        public void onCapabilitiesChanged(Network network,
                 NetworkCapabilities networkCapabilities) {}
 
         /**
          * Called when the network the framework connected to for this request
          * changes {@link LinkProperties}.
          *
-         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
          * @param network The {@link Network} whose link properties have changed.
          * @param linkProperties The new {@link LinkProperties} for this network.
          */
-        public void onLinkPropertiesChanged(NetworkRequest networkRequest, Network network,
-                LinkProperties linkProperties) {}
+        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
 
-        /**
-         * Called when a {@link #releaseNetworkRequest} call concludes and the registered
-         * callbacks will no longer be used.
-         *
-         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
-         */
-        public void onReleased(NetworkRequest networkRequest) {}
+        private NetworkRequest networkRequest;
     }
 
     private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
@@ -2007,12 +2007,12 @@
     private static final int EXPIRE_LEGACY_REQUEST      = BASE + 10;
 
     private class CallbackHandler extends Handler {
-        private final HashMap<NetworkRequest, NetworkCallbackListener>mCallbackMap;
+        private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
         private final AtomicInteger mRefCount;
         private static final String TAG = "ConnectivityManager.CallbackHandler";
         private final ConnectivityManager mCm;
 
-        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallbackListener>callbackMap,
+        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
                 AtomicInteger refCount, ConnectivityManager cm) {
             super(looper);
             mCallbackMap = callbackMap;
@@ -2026,9 +2026,9 @@
             switch (message.what) {
                 case CALLBACK_PRECHECK: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbackListener callbacks = getCallbacks(request);
+                    NetworkCallback callbacks = getCallbacks(request);
                     if (callbacks != null) {
-                        callbacks.onPreCheck(request, getNetwork(message));
+                        callbacks.onPreCheck(getNetwork(message));
                     } else {
                         Log.e(TAG, "callback not found for PRECHECK message");
                     }
@@ -2036,9 +2036,9 @@
                 }
                 case CALLBACK_AVAILABLE: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbackListener callbacks = getCallbacks(request);
+                    NetworkCallback callbacks = getCallbacks(request);
                     if (callbacks != null) {
-                        callbacks.onAvailable(request, getNetwork(message));
+                        callbacks.onAvailable(getNetwork(message));
                     } else {
                         Log.e(TAG, "callback not found for AVAILABLE message");
                     }
@@ -2046,9 +2046,9 @@
                 }
                 case CALLBACK_LOSING: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbackListener callbacks = getCallbacks(request);
+                    NetworkCallback callbacks = getCallbacks(request);
                     if (callbacks != null) {
-                        callbacks.onLosing(request, getNetwork(message), message.arg1);
+                        callbacks.onLosing(getNetwork(message), message.arg1);
                     } else {
                         Log.e(TAG, "callback not found for LOSING message");
                     }
@@ -2056,9 +2056,9 @@
                 }
                 case CALLBACK_LOST: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbackListener callbacks = getCallbacks(request);
+                    NetworkCallback callbacks = getCallbacks(request);
                     if (callbacks != null) {
-                        callbacks.onLost(request, getNetwork(message));
+                        callbacks.onLost(getNetwork(message));
                     } else {
                         Log.e(TAG, "callback not found for LOST message");
                     }
@@ -2066,12 +2066,12 @@
                 }
                 case CALLBACK_UNAVAIL: {
                     NetworkRequest req = (NetworkRequest)message.obj;
-                    NetworkCallbackListener callbacks = null;
+                    NetworkCallback callbacks = null;
                     synchronized(mCallbackMap) {
                         callbacks = mCallbackMap.get(req);
                     }
                     if (callbacks != null) {
-                        callbacks.onUnavailable(req);
+                        callbacks.onUnavailable();
                     } else {
                         Log.e(TAG, "callback not found for UNAVAIL message");
                     }
@@ -2079,12 +2079,12 @@
                 }
                 case CALLBACK_CAP_CHANGED: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbackListener callbacks = getCallbacks(request);
+                    NetworkCallback callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         Network network = getNetwork(message);
                         NetworkCapabilities cap = mCm.getNetworkCapabilities(network);
 
-                        callbacks.onNetworkCapabilitiesChanged(request, network, cap);
+                        callbacks.onCapabilitiesChanged(network, cap);
                     } else {
                         Log.e(TAG, "callback not found for CHANGED message");
                     }
@@ -2092,12 +2092,12 @@
                 }
                 case CALLBACK_IP_CHANGED: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbackListener callbacks = getCallbacks(request);
+                    NetworkCallback callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         Network network = getNetwork(message);
                         LinkProperties lp = mCm.getLinkProperties(network);
 
-                        callbacks.onLinkPropertiesChanged(request, network, lp);
+                        callbacks.onLinkPropertiesChanged(network, lp);
                     } else {
                         Log.e(TAG, "callback not found for CHANGED message");
                     }
@@ -2105,20 +2105,19 @@
                 }
                 case CALLBACK_RELEASED: {
                     NetworkRequest req = (NetworkRequest)message.obj;
-                    NetworkCallbackListener callbacks = null;
+                    NetworkCallback callbacks = null;
                     synchronized(mCallbackMap) {
                         callbacks = mCallbackMap.remove(req);
                     }
                     if (callbacks != null) {
-                        callbacks.onReleased(req);
+                        synchronized(mRefCount) {
+                            if (mRefCount.decrementAndGet() == 0) {
+                                getLooper().quit();
+                            }
+                        }
                     } else {
                         Log.e(TAG, "callback not found for CANCELED message");
                     }
-                    synchronized(mRefCount) {
-                        if (mRefCount.decrementAndGet() == 0) {
-                            getLooper().quit();
-                        }
-                    }
                     break;
                 }
                 case CALLBACK_EXIT: {
@@ -2136,7 +2135,7 @@
         private NetworkRequest getNetworkRequest(Message msg) {
             return (NetworkRequest)(msg.obj);
         }
-        private NetworkCallbackListener getCallbacks(NetworkRequest req) {
+        private NetworkCallback getCallbacks(NetworkRequest req) {
             synchronized(mCallbackMap) {
                 return mCallbackMap.get(req);
             }
@@ -2144,7 +2143,7 @@
         private Network getNetwork(Message msg) {
             return new Network(msg.arg2);
         }
-        private NetworkCallbackListener removeCallbacks(Message msg) {
+        private NetworkCallback removeCallbacks(Message msg) {
             NetworkRequest req = (NetworkRequest)msg.obj;
             synchronized(mCallbackMap) {
                 return mCallbackMap.remove(req);
@@ -2152,19 +2151,19 @@
         }
     }
 
-    private void addCallbackListener() {
+    private void incCallbackHandlerRefCount() {
         synchronized(sCallbackRefCount) {
             if (sCallbackRefCount.incrementAndGet() == 1) {
                 // TODO - switch this over to a ManagerThread or expire it when done
                 HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
                 callbackThread.start();
                 sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
-                        sNetworkCallbackListener, sCallbackRefCount, this);
+                        sNetworkCallback, sCallbackRefCount, this);
             }
         }
     }
 
-    private void removeCallbackListener() {
+    private void decCallbackHandlerRefCount() {
         synchronized(sCallbackRefCount) {
             if (sCallbackRefCount.decrementAndGet() == 0) {
                 sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
@@ -2173,8 +2172,8 @@
         }
     }
 
-    static final HashMap<NetworkRequest, NetworkCallbackListener> sNetworkCallbackListener =
-            new HashMap<NetworkRequest, NetworkCallbackListener>();
+    static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
+            new HashMap<NetworkRequest, NetworkCallback>();
     static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
     static CallbackHandler sCallbackHandler = null;
 
@@ -2182,51 +2181,48 @@
     private final static int REQUEST = 2;
 
     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
-            NetworkCallbackListener networkCallbackListener, int timeoutSec, int action,
+            NetworkCallback networkCallback, int timeoutSec, int action,
             int legacyType) {
-        NetworkRequest networkRequest = null;
-        if (networkCallbackListener == null) {
-            throw new IllegalArgumentException("null NetworkCallbackListener");
+        if (networkCallback == null) {
+            throw new IllegalArgumentException("null NetworkCallback");
         }
         if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
         try {
-            addCallbackListener();
+            incCallbackHandlerRefCount();
             if (action == LISTEN) {
-                networkRequest = mService.listenForNetwork(need, new Messenger(sCallbackHandler),
-                        new Binder());
+                networkCallback.networkRequest = mService.listenForNetwork(need,
+                        new Messenger(sCallbackHandler), new Binder());
             } else {
-                networkRequest = mService.requestNetwork(need, new Messenger(sCallbackHandler),
-                        timeoutSec, new Binder(), legacyType);
+                networkCallback.networkRequest = mService.requestNetwork(need,
+                        new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
             }
-            if (networkRequest != null) {
-                synchronized(sNetworkCallbackListener) {
-                    sNetworkCallbackListener.put(networkRequest, networkCallbackListener);
+            if (networkCallback.networkRequest != null) {
+                synchronized(sNetworkCallback) {
+                    sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
                 }
             }
         } catch (RemoteException e) {}
-        if (networkRequest == null) removeCallbackListener();
-        return networkRequest;
+        if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
+        return networkCallback.networkRequest;
     }
 
     /**
      * Request a network to satisfy a set of {@link NetworkCapabilities}.
      *
      * This {@link NetworkRequest} will live until released via
-     * {@link #releaseNetworkRequest} or the calling application exits.
+     * {@link #unregisterNetworkCallback} or the calling application exits.
      * Status of the request can be followed by listening to the various
-     * callbacks described in {@link NetworkCallbackListener}.  The {@link Network}
+     * callbacks described in {@link NetworkCallback}.  The {@link Network}
      * can be used to direct traffic to the network.
      *
-     * @param need {@link NetworkCapabilities} required by this request.
-     * @param networkCallbackListener The {@link NetworkCallbackListener} to be utilized for this
-     *                         request.  Note the callbacks can be shared by multiple
-     *                         requests and the NetworkRequest token utilized to
-     *                         determine to which request the callback relates.
-     * @return A {@link NetworkRequest} object identifying the request.
+     * @param request {@link NetworkRequest} describing this request.
+     * @param networkCallback The {@link NetworkCallback} to be utilized for this
+     *                        request.  Note the callback must not be shared - they
+     *                        uniquely specify this request.
      */
-    public NetworkRequest requestNetwork(NetworkCapabilities need,
-            NetworkCallbackListener networkCallbackListener) {
-        return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, TYPE_NONE);
+    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
+        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
+                REQUEST, TYPE_NONE);
     }
 
     /**
@@ -2234,53 +2230,53 @@
      * by a timeout.
      *
      * This function behaves identically to the non-timedout version, but if a suitable
-     * network is not found within the given time (in Seconds) the
-     * {@link NetworkCallbackListener#unavailable} callback is called.  The request must
+     * network is not found within the given time (in milliseconds) the
+     * {@link NetworkCallback#unavailable} callback is called.  The request must
      * still be released normally by calling {@link releaseNetworkRequest}.
-     * @param need {@link NetworkCapabilities} required by this request.
-     * @param networkCallbackListener The callbacks to be utilized for this request.  Note
-     *                         the callbacks can be shared by multiple requests and
-     *                         the NetworkRequest token utilized to determine to which
-     *                         request the callback relates.
-     * @param timeoutSec The time in seconds to attempt looking for a suitable network
-     *                   before {@link NetworkCallbackListener#unavailable} is called.
-     * @return A {@link NetworkRequest} object identifying the request.
+     * @param request {@link NetworkRequest} describing this request.
+     * @param networkCallback The callbacks to be utilized for this request.  Note
+     *                        the callbacks must not be shared - they uniquely specify
+     *                        this request.
+     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
+     *                  before {@link NetworkCallback#unavailable} is called.
      * @hide
      */
-    public NetworkRequest requestNetwork(NetworkCapabilities need,
-            NetworkCallbackListener networkCallbackListener, int timeoutSec) {
-        return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST,
-                TYPE_NONE);
+    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
+            int timeoutMs) {
+        sendRequestForNetwork(request.networkCapabilities, networkCallback, timeoutMs,
+                REQUEST, TYPE_NONE);
     }
 
     /**
-     * The maximum number of seconds the framework will look for a suitable network
+     * The maximum number of milliseconds the framework will look for a suitable network
      * during a timeout-equiped call to {@link requestNetwork}.
      * {@hide}
      */
-    public final static int MAX_NETWORK_REQUEST_TIMEOUT_SEC = 100 * 60;
+    public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000;
 
     /**
      * The lookup key for a {@link Network} object included with the intent after
      * succesfully finding a network for the applications request.  Retrieve it with
      * {@link android.content.Intent#getParcelableExtra(String)}.
+     * @hide
      */
     public static final String EXTRA_NETWORK_REQUEST_NETWORK = "networkRequestNetwork";
 
     /**
-     * The lookup key for a {@link NetworkCapabilities} object included with the intent after
+     * The lookup key for a {@link NetworkRequest} object included with the intent after
      * succesfully finding a network for the applications request.  Retrieve it with
      * {@link android.content.Intent#getParcelableExtra(String)}.
+     * @hide
      */
-    public static final String EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES =
-            "networkRequestNetworkCapabilities";
+    public static final String EXTRA_NETWORK_REQUEST_NETWORK_REQUEST =
+            "networkRequestNetworkRequest";
 
 
     /**
      * Request a network to satisfy a set of {@link NetworkCapabilities}.
      *
-     * This function behavies identically to the callback-equiped version, but instead
-     * of {@link NetworkCallbackListener} a {@link PendingIntent} is used.  This means
+     * This function behavies identically to the version that takes a NetworkCallback, but instead
+     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
      * the request may outlive the calling application and get called back when a suitable
      * network is found.
      * <p>
@@ -2289,10 +2285,10 @@
      * &lt;receiver&gt; tag in an AndroidManifest.xml file
      * <p>
      * The operation Intent is delivered with two extras, a {@link Network} typed
-     * extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkCapabilities}
-     * typed extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES} containing
+     * extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkRequest}
+     * typed extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK_REQUEST} containing
      * the original requests parameters.  It is important to create a new,
-     * {@link NetworkCallbackListener} based request before completing the processing of the
+     * {@link NetworkCallback} based request before completing the processing of the
      * Intent to reserve the network or it will be released shortly after the Intent
      * is processed.
      * <p>
@@ -2300,51 +2296,109 @@
      * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
      * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
      * <p>
-     * The request may be released normally by calling {@link #releaseNetworkRequest}.
+     * The request may be released normally by calling {@link #unregisterNetworkCallback}.
      *
-     * @param need {@link NetworkCapabilities} required by this request.
+     * @param request {@link NetworkRequest} describing this request.
      * @param operation Action to perform when the network is available (corresponds
-     *                  to the {@link NetworkCallbackListener#onAvailable} call.  Typically
+     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
      *                  comes from {@link PendingIntent#getBroadcast}.
-     * @return A {@link NetworkRequest} object identifying the request.
+     * @hide
      */
-    public NetworkRequest requestNetwork(NetworkCapabilities need, PendingIntent operation) {
+    public void requestNetwork(NetworkRequest request, PendingIntent operation) {
         try {
-            return mService.pendingRequestForNetwork(need, operation);
+            mService.pendingRequestForNetwork(request.networkCapabilities, operation);
         } catch (RemoteException e) {}
-        return null;
     }
 
     /**
      * Registers to receive notifications about all networks which satisfy the given
-     * {@link NetworkCapabilities}.  The callbacks will continue to be called until
-     * either the application exits or the request is released using
-     * {@link #releaseNetworkRequest}.
+     * {@link NetworkRequest}.  The callbacks will continue to be called until
+     * either the application exits or {@link #unregisterNetworkCallback} is called
      *
-     * @param need {@link NetworkCapabilities} required by this request.
-     * @param networkCallbackListener The {@link NetworkCallbackListener} to be called as suitable
-     *                         networks change state.
-     * @return A {@link NetworkRequest} object identifying the request.
+     * @param request {@link NetworkRequest} describing this request.
+     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
+     *                        networks change state.
      */
-    public NetworkRequest listenForNetwork(NetworkCapabilities need,
-            NetworkCallbackListener networkCallbackListener) {
-        return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, TYPE_NONE);
+    public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
+        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE);
     }
 
     /**
-     * Releases a {@link NetworkRequest} generated either through a {@link #requestNetwork}
-     * or a {@link #listenForNetwork} call.  The {@link NetworkCallbackListener} given in the
-     * earlier call may continue receiving calls until the
-     * {@link NetworkCallbackListener#onReleased} function is called, signifying the end
-     * of the request.
+     * Unregisters callbacks about and possibly releases networks originating from
+     * {@link #requestNetwork} and {@link #registerNetworkCallback} calls.  If the
+     * given {@code NetworkCallback} had previosuly been used with {@code #requestNetwork},
+     * any networks that had been connected to only to satisfy that request will be
+     * disconnected.
      *
-     * @param networkRequest The {@link NetworkRequest} generated by an earlier call to
-     *                       {@link #requestNetwork} or {@link #listenForNetwork}.
+     * @param networkCallback The {@link NetworkCallback} used when making the request.
      */
-    public void releaseNetworkRequest(NetworkRequest networkRequest) {
-        if (networkRequest == null) throw new IllegalArgumentException("null NetworkRequest");
+    public void unregisterNetworkCallback(NetworkCallback networkCallback) {
+        if (networkCallback == null || networkCallback.networkRequest == null ||
+                networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) {
+            throw new IllegalArgumentException("Invalid NetworkCallback");
+        }
         try {
-            mService.releaseNetworkRequest(networkRequest);
+            mService.releaseNetworkRequest(networkCallback.networkRequest);
         } catch (RemoteException e) {}
     }
+
+    /**
+     * Binds the current process to {@code network}.  All Sockets created in the future
+     * (and not explicitly bound via a bound SocketFactory from
+     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
+     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
+     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
+     * work and all host name resolutions will fail.  This is by design so an application doesn't
+     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
+     * To clear binding pass {@code null} for {@code network}.  Using individually bound
+     * Sockets created by Network.getSocketFactory().createSocket() and
+     * performing network-specific host name resolutions via
+     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
+     * {@code setProcessDefaultNetwork}.
+     *
+     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
+     *                the current binding.
+     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
+     */
+    public static boolean setProcessDefaultNetwork(Network network) {
+        if (network == null) {
+            NetworkUtils.unbindProcessToNetwork();
+        } else {
+            NetworkUtils.bindProcessToNetwork(network.netId);
+        }
+        // TODO fix return value
+        return true;
+    }
+
+    /**
+     * Returns the {@link Network} currently bound to this process via
+     * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound.
+     *
+     * @return {@code Network} to which this process is bound, or {@code null}.
+     */
+    public static Network getProcessDefaultNetwork() {
+        int netId = NetworkUtils.getNetworkBoundToProcess();
+        if (netId == 0) return null;
+        return new Network(netId);
+    }
+
+    /**
+     * Binds host resolutions performed by this process to {@code network}.
+     * {@link #setProcessDefaultNetwork} takes precedence over this setting.
+     *
+     * @param network The {@link Network} to bind host resolutions from the current process to, or
+     *                {@code null} to clear the current binding.
+     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
+     * @hide
+     * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
+     */
+    public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
+        if (network == null) {
+            NetworkUtils.unbindProcessToNetworkForHostResolution();
+        } else {
+            NetworkUtils.bindProcessToNetworkForHostResolution(network.netId);
+        }
+        // TODO hook up the return value.
+        return true;
+    }
 }
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 22b26b1..49a307e 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -74,8 +74,10 @@
         if (linkProperties.getRoutes().size() == 0) {
             for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r);
         }
-        if (linkProperties.getDnses().size() == 0) {
-            for (InetAddress d : orig.linkProperties.getDnses()) linkProperties.addDns(d);
+        if (linkProperties.getDnsServers().size() == 0) {
+            for (InetAddress d : orig.linkProperties.getDnsServers()) {
+                linkProperties.addDnsServer(d);
+            }
         }
     }
 
@@ -211,7 +213,7 @@
     public boolean addDns(String addrString) {
         if (TextUtils.isEmpty(addrString) == false) {
             try {
-                linkProperties.addDns(NetworkUtils.numericToInetAddress(addrString));
+                linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString));
             } catch (IllegalArgumentException e) {
                 Log.e(TAG, "addDns failed with addrString " + addrString);
                 return true;
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index 66f0fd0..7acf3f5 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -248,7 +248,7 @@
             return mDefaultDns;
         }
 
-        Collection<InetAddress> dnses = curLinkProps.getDnses();
+        Collection<InetAddress> dnses = curLinkProps.getDnsServers();
         if (dnses == null || dnses.size() == 0) {
             loge("getDns::LinkProps has null dns - returning default");
             return mDefaultDns;
diff --git a/core/java/android/app/task/Task.aidl b/core/java/android/net/IpPrefix.aidl
similarity index 85%
copy from core/java/android/app/task/Task.aidl
copy to core/java/android/net/IpPrefix.aidl
index 1f25439..9e552c7 100644
--- a/core/java/android/app/task/Task.aidl
+++ b/core/java/android/net/IpPrefix.aidl
@@ -1,11 +1,12 @@
 /**
+ *
  * Copyright (C) 2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +15,6 @@
  * limitations under the License.
  */
 
-package android.app.task;
+package android.net;
 
-parcelable Task;
- 
\ No newline at end of file
+parcelable IpPrefix;
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
new file mode 100644
index 0000000..a14d13f
--- /dev/null
+++ b/core/java/android/net/IpPrefix.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/**
+ * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a
+ * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of
+ * information:
+ *
+ * <ul>
+ * <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix.
+ * <li>A prefix length. This specifies the length of the prefix by specifing the number of bits
+ *     in the IP address, starting from the most significant bit in network byte order, that
+ *     are constant for all addresses in the prefix.
+ * </ul>
+ *
+ * For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from
+ * <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix
+ * <code>2001:db8:1:2</code>  covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to
+ * <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive.
+ *
+ * Objects of this class are immutable.
+ */
+public final class IpPrefix implements Parcelable {
+    private final byte[] address;  // network byte order
+    private final int prefixLength;
+
+    /**
+     * Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
+     * network byte order and a prefix length.
+     *
+     * @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
+     * @param prefixLength the prefix length. Must be &gt;= 0 and &lt;= (32 or 128) (IPv4 or IPv6).
+     *
+     * @hide
+     */
+    public IpPrefix(byte[] address, int prefixLength) {
+        if (address.length != 4 && address.length != 16) {
+            throw new IllegalArgumentException(
+                    "IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
+        }
+        if (prefixLength < 0 || prefixLength > (address.length * 8)) {
+            throw new IllegalArgumentException("IpPrefix with " + address.length +
+                    " bytes has invalid prefix length " + prefixLength);
+        }
+        this.address = address.clone();
+        this.prefixLength = prefixLength;
+        // TODO: Validate that the non-prefix bits are zero
+    }
+
+    /**
+     * @hide
+     */
+    public IpPrefix(InetAddress address, int prefixLength) {
+        this(address.getAddress(), prefixLength);
+    }
+
+    /**
+     * Compares this {@code IpPrefix} object against the specified object in {@code obj}. Two
+     * objects are equal if they have the same startAddress and prefixLength.
+     *
+     * @param obj the object to be tested for equality.
+     * @return {@code true} if both objects are equal, {@code false} otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof IpPrefix)) {
+            return false;
+        }
+        IpPrefix that = (IpPrefix) obj;
+        return Arrays.equals(this.address, that.address) && this.prefixLength == that.prefixLength;
+    }
+
+    /**
+     * Gets the hashcode of the represented IP prefix.
+     *
+     * @return the appropriate hashcode value.
+     */
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(address) + 11 * prefixLength;
+    }
+
+    /**
+     * Returns a copy of the first IP address in the prefix. Modifying the returned object does not
+     * change this object's contents.
+     *
+     * @return the address in the form of a byte array.
+     */
+    public InetAddress getAddress() {
+        try {
+            return InetAddress.getByAddress(address);
+        } catch (UnknownHostException e) {
+            // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
+            // array is the wrong length, but we check that in the constructor.
+            return null;
+        }
+    }
+
+    /**
+     * Returns a copy of the IP address bytes in network order (the highest order byte is the zeroth
+     * element). Modifying the returned array does not change this object's contents.
+     *
+     * @return the address in the form of a byte array.
+     */
+    public byte[] getRawAddress() {
+        return address.clone();
+    }
+
+    /**
+     * Returns the prefix length of this {@code IpAddress}.
+     *
+     * @return the prefix length.
+     */
+    public int getPrefixLength() {
+        return prefixLength;
+    }
+
+    /**
+     * Implement the Parcelable interface.
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Implement the Parcelable interface.
+     */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeByteArray(address);
+        dest.writeInt(prefixLength);
+    }
+
+    /**
+     * Implement the Parcelable interface.
+     */
+    public static final Creator<IpPrefix> CREATOR =
+            new Creator<IpPrefix>() {
+                public IpPrefix createFromParcel(Parcel in) {
+                    byte[] address = in.createByteArray();
+                    int prefixLength = in.readInt();
+                    return new IpPrefix(address, prefixLength);
+                }
+
+                public IpPrefix[] newArray(int size) {
+                    return new IpPrefix[size];
+                }
+            };
+}
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index d07c0b61..5246078 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -39,18 +39,13 @@
  * <ul>
  * <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}).
  * The address must be unicast, as multicast addresses cannot be assigned to interfaces.
- * <li>Address flags: A bitmask of {@code IFA_F_*} values representing properties
- * of the address.
- * <li>Address scope: An integer defining the scope in which the address is unique (e.g.,
- * {@code RT_SCOPE_LINK} or {@code RT_SCOPE_SITE}).
- * <ul>
- *<p>
- * When constructing a {@code LinkAddress}, the IP address and prefix are required. The flags and
- * scope are optional. If they are not specified, the flags are set to zero, and the scope will be
- * determined based on the IP address (e.g., link-local addresses will be created with a scope of
- * {@code RT_SCOPE_LINK}, global addresses with {@code RT_SCOPE_UNIVERSE},
- * etc.) If they are specified, they are not checked for validity.
- *
+ * <li>Address flags: A bitmask of {@code OsConstants.IFA_F_*} values representing properties
+ * of the address (e.g., {@code android.system.OsConstants.IFA_F_OPTIMISTIC}).
+ * <li>Address scope: One of the {@code OsConstants.IFA_F_*} values; defines the scope in which
+ * the address is unique (e.g.,
+ * {@code android.system.OsConstants.RT_SCOPE_LINK} or
+ * {@code android.system.OsConstants.RT_SCOPE_UNIVERSE}).
+ * </ul>
  */
 public class LinkAddress implements Parcelable {
     /**
@@ -202,7 +197,9 @@
 
     /**
      * Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if
-     * their address, prefix length, flags and scope are equal.
+     * their address, prefix length, flags and scope are equal. Thus, for example, two addresses
+     * that have the same address and prefix length are not equal if one of them is deprecated and
+     * the other is not.
      *
      * @param obj the object to be tested for equality.
      * @return {@code true} if both objects are equal, {@code false} otherwise.
@@ -236,6 +233,7 @@
      * @param other the {@code LinkAddress} to compare to.
      * @return {@code true} if both objects have the same address and prefix length, {@code false}
      * otherwise.
+     * @hide
      */
     public boolean isSameAddressAs(LinkAddress other) {
         return address.equals(other.address) && prefixLength == other.prefixLength;
@@ -251,11 +249,20 @@
     /**
      * Returns the prefix length of this {@code LinkAddress}.
      */
-    public int getNetworkPrefixLength() {
+    public int getPrefixLength() {
         return prefixLength;
     }
 
     /**
+     * Returns the prefix length of this {@code LinkAddress}.
+     * TODO: Delete all callers and remove in favour of getPrefixLength().
+     * @hide
+     */
+    public int getNetworkPrefixLength() {
+        return getPrefixLength();
+    }
+
+    /**
      * Returns the flags of this {@code LinkAddress}.
      */
     public int getFlags() {
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 3c36679..8eefa0f 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -30,6 +30,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Hashtable;
+import java.util.List;
 
 /**
  * Describes the properties of a network link.
@@ -43,7 +44,7 @@
  * does not affect live networks.
  *
  */
-public class LinkProperties implements Parcelable {
+public final class LinkProperties implements Parcelable {
     // The interface described by the network link.
     private String mIfaceName;
     private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
@@ -58,10 +59,12 @@
     private Hashtable<String, LinkProperties> mStackedLinks =
         new Hashtable<String, LinkProperties>();
 
-    // @hide
+    /**
+     * @hide
+     */
     public static class CompareResult<T> {
-        public Collection<T> removed = new ArrayList<T>();
-        public Collection<T> added = new ArrayList<T>();
+        public List<T> removed = new ArrayList<T>();
+        public List<T> added = new ArrayList<T>();
 
         @Override
         public String toString() {
@@ -74,14 +77,20 @@
         }
     }
 
+    /**
+     * @hide
+     */
     public LinkProperties() {
     }
 
+    /**
+     * @hide
+     */
     public LinkProperties(LinkProperties source) {
         if (source != null) {
             mIfaceName = source.getInterfaceName();
             for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
-            for (InetAddress i : source.getDnses()) mDnses.add(i);
+            for (InetAddress i : source.getDnsServers()) mDnses.add(i);
             mDomains = source.getDomains();
             for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
             mHttpProxy = (source.getHttpProxy() == null)  ?
@@ -98,6 +107,7 @@
      * will have their interface changed to match this new value.
      *
      * @param iface The name of the network interface used for this link.
+     * @hide
      */
     public void setInterfaceName(String iface) {
         mIfaceName = iface;
@@ -117,9 +127,11 @@
         return mIfaceName;
     }
 
-    // @hide
-    public Collection<String> getAllInterfaceNames() {
-        Collection interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
+    /**
+     * @hide
+     */
+    public List<String> getAllInterfaceNames() {
+        List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
         if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
         for (LinkProperties stacked: mStackedLinks.values()) {
             interfaceNames.addAll(stacked.getAllInterfaceNames());
@@ -134,23 +146,23 @@
      * prefix lengths for each address.  This is a simplified utility alternative to
      * {@link LinkProperties#getLinkAddresses}.
      *
-     * @return An umodifiable {@link Collection} of {@link InetAddress} for this link.
+     * @return An umodifiable {@link List} of {@link InetAddress} for this link.
      * @hide
      */
-    public Collection<InetAddress> getAddresses() {
-        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+    public List<InetAddress> getAddresses() {
+        List<InetAddress> addresses = new ArrayList<InetAddress>();
         for (LinkAddress linkAddress : mLinkAddresses) {
             addresses.add(linkAddress.getAddress());
         }
-        return Collections.unmodifiableCollection(addresses);
+        return Collections.unmodifiableList(addresses);
     }
 
     /**
      * Returns all the addresses on this link and all the links stacked above it.
      * @hide
      */
-    public Collection<InetAddress> getAllAddresses() {
-        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+    public List<InetAddress> getAllAddresses() {
+        List<InetAddress> addresses = new ArrayList<InetAddress>();
         for (LinkAddress linkAddress : mLinkAddresses) {
             addresses.add(linkAddress.getAddress());
         }
@@ -174,6 +186,7 @@
      * same address/prefix does not already exist.  If it does exist it is replaced.
      * @param address The {@code LinkAddress} to add.
      * @return true if {@code address} was added or updated, false otherwise.
+     * @hide
      */
     public boolean addLinkAddress(LinkAddress address) {
         if (address == null) {
@@ -200,6 +213,7 @@
      *
      * @param toRemove A {@link LinkAddress} specifying the address to remove.
      * @return true if the address was removed, false if it did not exist.
+     * @hide
      */
     public boolean removeLinkAddress(LinkAddress toRemove) {
         int i = findLinkAddressIndex(toRemove);
@@ -214,18 +228,18 @@
      * Returns all the {@link LinkAddress} on this link.  Typically a link will have
      * one IPv4 address and one or more IPv6 addresses.
      *
-     * @return An unmodifiable {@link Collection} of {@link LinkAddress} for this link.
+     * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
      */
-    public Collection<LinkAddress> getLinkAddresses() {
-        return Collections.unmodifiableCollection(mLinkAddresses);
+    public List<LinkAddress> getLinkAddresses() {
+        return Collections.unmodifiableList(mLinkAddresses);
     }
 
     /**
      * Returns all the addresses on this link and all the links stacked above it.
      * @hide
      */
-    public Collection<LinkAddress> getAllLinkAddresses() {
-        Collection<LinkAddress> addresses = new ArrayList<LinkAddress>();
+    public List<LinkAddress> getAllLinkAddresses() {
+        List<LinkAddress> addresses = new ArrayList<LinkAddress>();
         addresses.addAll(mLinkAddresses);
         for (LinkProperties stacked: mStackedLinks.values()) {
             addresses.addAll(stacked.getAllLinkAddresses());
@@ -239,6 +253,7 @@
      *
      * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
      *                  object.
+     * @hide
      */
     public void setLinkAddresses(Collection<LinkAddress> addresses) {
         mLinkAddresses.clear();
@@ -250,20 +265,21 @@
     /**
      * Adds the given {@link InetAddress} to the list of DNS servers.
      *
-     * @param dns The {@link InetAddress} to add to the list of DNS servers.
+     * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
+     * @hide
      */
-    public void addDns(InetAddress dns) {
-        if (dns != null) mDnses.add(dns);
+    public void addDnsServer(InetAddress dnsServer) {
+        if (dnsServer != null) mDnses.add(dnsServer);
     }
 
     /**
-     * Returns all the {@link LinkAddress} for DNS servers on this link.
+     * Returns all the {@link InetAddress} for DNS servers on this link.
      *
-     * @return An umodifiable {@link Collection} of {@link InetAddress} for DNS servers on
+     * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
      *         this link.
      */
-    public Collection<InetAddress> getDnses() {
-        return Collections.unmodifiableCollection(mDnses);
+    public List<InetAddress> getDnsServers() {
+        return Collections.unmodifiableList(mDnses);
     }
 
     /**
@@ -271,6 +287,7 @@
      *
      * @param domains A {@link String} listing in priority order the comma separated
      *                domains to search when resolving host names on this link.
+     * @hide
      */
     public void setDomains(String domains) {
         mDomains = domains;
@@ -323,6 +340,7 @@
      * proper course is to add either un-named or properly named {@link RouteInfo}.
      *
      * @param route A {@link RouteInfo} to add to this object.
+     * @hide
      */
     public void addRoute(RouteInfo route) {
         if (route != null) {
@@ -339,18 +357,18 @@
     /**
      * Returns all the {@link RouteInfo} set on this link.
      *
-     * @return An unmodifiable {@link Collection} of {@link RouteInfo} for this link.
+     * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
      */
-    public Collection<RouteInfo> getRoutes() {
-        return Collections.unmodifiableCollection(mRoutes);
+    public List<RouteInfo> getRoutes() {
+        return Collections.unmodifiableList(mRoutes);
     }
 
     /**
      * Returns all the routes on this link and all the links stacked above it.
      * @hide
      */
-    public Collection<RouteInfo> getAllRoutes() {
-        Collection<RouteInfo> routes = new ArrayList();
+    public List<RouteInfo> getAllRoutes() {
+        List<RouteInfo> routes = new ArrayList();
         routes.addAll(mRoutes);
         for (LinkProperties stacked: mStackedLinks.values()) {
             routes.addAll(stacked.getAllRoutes());
@@ -364,6 +382,7 @@
      * not enforce it and applications may ignore them.
      *
      * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+     * @hide
      */
     public void setHttpProxy(ProxyInfo proxy) {
         mHttpProxy = proxy;
@@ -419,16 +438,17 @@
      * Returns all the links stacked on top of this link.
      * @hide
      */
-    public Collection<LinkProperties> getStackedLinks() {
-        Collection<LinkProperties> stacked = new ArrayList<LinkProperties>();
+    public List<LinkProperties> getStackedLinks() {
+        List<LinkProperties> stacked = new ArrayList<LinkProperties>();
         for (LinkProperties link : mStackedLinks.values()) {
           stacked.add(new LinkProperties(link));
         }
-        return Collections.unmodifiableCollection(stacked);
+        return Collections.unmodifiableList(stacked);
     }
 
     /**
      * Clears this object to its initial state.
+     * @hide
      */
     public void clear() {
         mIfaceName = null;
@@ -443,7 +463,6 @@
 
     /**
      * Implement the Parcelable interface
-     * @hide
      */
     public int describeContents() {
         return 0;
@@ -463,12 +482,12 @@
 
         String domainName = "Domains: " + mDomains;
 
-        String mtu = "MTU: " + mMtu;
+        String mtu = " MTU: " + mMtu;
 
         String routes = " Routes: [";
         for (RouteInfo route : mRoutes) routes += route.toString() + ",";
         routes += "] ";
-        String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
+        String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
 
         String stacked = "";
         if (mStackedLinks.values().size() > 0) {
@@ -486,6 +505,7 @@
      * Returns true if this link has an IPv4 address.
      *
      * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
+     * @hide
      */
     public boolean hasIPv4Address() {
         for (LinkAddress address : mLinkAddresses) {
@@ -500,6 +520,7 @@
      * Returns true if this link has an IPv6 address.
      *
      * @return {@code true} if there is an IPv6 address, {@code false} otherwise.
+     * @hide
      */
     public boolean hasIPv6Address() {
         for (LinkAddress address : mLinkAddresses) {
@@ -543,7 +564,7 @@
      * @hide
      */
     public boolean isIdenticalDnses(LinkProperties target) {
-        Collection<InetAddress> targetDnses = target.getDnses();
+        Collection<InetAddress> targetDnses = target.getDnsServers();
         String targetDomains = target.getDomains();
         if (mDomains == null) {
             if (targetDomains != null) return false;
@@ -696,7 +717,7 @@
         result.removed = new ArrayList<InetAddress>(mDnses);
         result.added.clear();
         if (target != null) {
-            for (InetAddress newAddress : target.getDnses()) {
+            for (InetAddress newAddress : target.getDnsServers()) {
                 if (! result.removed.remove(newAddress)) {
                     result.added.add(newAddress);
                 }
@@ -831,7 +852,7 @@
                 addressCount = in.readInt();
                 for (int i=0; i<addressCount; i++) {
                     try {
-                        netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
+                        netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
                     } catch (UnknownHostException e) { }
                 }
                 netProp.setDomains(in.readString());
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 64516e6..318aabe 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -29,10 +29,12 @@
 
 /**
  * Identifies a {@code Network}.  This is supplied to applications via
- * {@link ConnectivityManager.NetworkCallbackListener} in response to
- * {@link ConnectivityManager#requestNetwork} or {@link ConnectivityManager#listenForNetwork}.
+ * {@link ConnectivityManager.NetworkCallback} in response to the active
+ * {@link ConnectivityManager#requestNetwork} or passive
+ * {@link ConnectivityManager#registerNetworkCallback} calls.
  * It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis
- * through a targeted {@link SocketFactory} or process-wide via {@link #bindProcess}.
+ * through a targeted {@link SocketFactory} or process-wide via
+ * {@link ConnectivityManager#setProcessDefaultNetwork}.
  */
 public class Network implements Parcelable {
 
@@ -160,63 +162,13 @@
      * @return a {@link SocketFactory} which produces {@link Socket} instances bound to this
      *         {@code Network}.
      */
-    public SocketFactory socketFactory() {
+    public SocketFactory getSocketFactory() {
         if (mNetworkBoundSocketFactory == null) {
             mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
         }
         return mNetworkBoundSocketFactory;
     }
 
-    /**
-     * Binds the current process to this network.  All sockets created in the future (and not
-     * explicitly bound via a bound {@link SocketFactory} (see {@link Network#socketFactory})
-     * will be bound to this network.  Note that if this {@code Network} ever disconnects
-     * all sockets created in this way will cease to work.  This is by design so an application
-     * doesn't accidentally use sockets it thinks are still bound to a particular {@code Network}.
-     */
-    public void bindProcess() {
-        NetworkUtils.bindProcessToNetwork(netId);
-    }
-
-    /**
-     * Binds host resolutions performed by this process to this network.  {@link #bindProcess}
-     * takes precedence over this setting.
-     *
-     * @hide
-     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
-     */
-    public void bindProcessForHostResolution() {
-        NetworkUtils.bindProcessToNetworkForHostResolution(netId);
-    }
-
-    /**
-     * Clears any process specific {@link Network} binding for host resolution.  This does
-     * not clear bindings enacted via {@link #bindProcess}.
-     *
-     * @hide
-     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
-     */
-    public void unbindProcessForHostResolution() {
-        NetworkUtils.unbindProcessToNetworkForHostResolution();
-    }
-
-    /**
-     * A static utility method to return any {@code Network} currently bound by this process.
-     *
-     * @return {@code Network} to which this process is bound.
-     */
-    public static Network getProcessBoundNetwork() {
-        return new Network(NetworkUtils.getNetworkBoundToProcess());
-    }
-
-    /**
-     * Clear any process specific {@code Network} binding.  This reverts a call to
-     * {@link Network#bindProcess}.
-     */
-    public static void unbindProcess() {
-        NetworkUtils.unbindProcessToNetwork();
-    }
-
     // implement the Parcelable interface
     public int describeContents() {
         return 0;
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 35274f1..fe96287 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -44,6 +44,9 @@
     private static final String TAG = "NetworkCapabilities";
     private static final boolean DBG = false;
 
+    /**
+     * @hide
+     */
     public NetworkCapabilities() {
     }
 
@@ -154,58 +157,64 @@
      * Multiple capabilities may be applied sequentially.  Note that when searching
      * for a network to satisfy a request, all capabilities requested must be satisfied.
      *
-     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+     * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void addNetworkCapability(int networkCapability) {
-        if (networkCapability < MIN_NET_CAPABILITY ||
-                networkCapability > MAX_NET_CAPABILITY) {
+    public NetworkCapabilities addCapability(int capability) {
+        if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             throw new IllegalArgumentException("NetworkCapability out of range");
         }
-        mNetworkCapabilities |= 1 << networkCapability;
+        mNetworkCapabilities |= 1 << capability;
+        return this;
     }
 
     /**
      * Removes (if found) the given capability from this {@code NetworkCapability} instance.
      *
-     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+     * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void removeNetworkCapability(int networkCapability) {
-        if (networkCapability < MIN_NET_CAPABILITY ||
-                networkCapability > MAX_NET_CAPABILITY) {
+    public NetworkCapabilities removeCapability(int capability) {
+        if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             throw new IllegalArgumentException("NetworkCapability out of range");
         }
-        mNetworkCapabilities &= ~(1 << networkCapability);
+        mNetworkCapabilities &= ~(1 << capability);
+        return this;
     }
 
     /**
      * Gets all the capabilities set on this {@code NetworkCapability} instance.
      *
-     * @return a {@link Collection} of {@code NetworkCapabilities.NET_CAPABILITY_*} values
+     * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
      *         for this instance.
+     * @hide
      */
-    public Collection<Integer> getNetworkCapabilities() {
+    public int[] getCapabilities() {
         return enumerateBits(mNetworkCapabilities);
     }
 
     /**
      * Tests for the presence of a capabilitity on this instance.
      *
-     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
+     * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
      * @return {@code true} if set on this instance.
      */
-    public boolean hasCapability(int networkCapability) {
-        if (networkCapability < MIN_NET_CAPABILITY ||
-                networkCapability > MAX_NET_CAPABILITY) {
+    public boolean hasCapability(int capability) {
+        if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             return false;
         }
-        return ((mNetworkCapabilities & (1 << networkCapability)) != 0);
+        return ((mNetworkCapabilities & (1 << capability)) != 0);
     }
 
-    private Collection<Integer> enumerateBits(long val) {
-        ArrayList<Integer> result = new ArrayList<Integer>();
+    private int[] enumerateBits(long val) {
+        int size = Long.bitCount(val);
+        int[] result = new int[size];
+        int index = 0;
         int resource = 0;
         while (val > 0) {
-            if ((val & 1) == 1) result.add(resource);
+            if ((val & 1) == 1) result[index++] = resource;
             val = val >> 1;
             resource++;
         }
@@ -265,33 +274,40 @@
      * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
      *
      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void addTransportType(int transportType) {
+    public NetworkCapabilities addTransportType(int transportType) {
         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
             throw new IllegalArgumentException("TransportType out of range");
         }
         mTransportTypes |= 1 << transportType;
+        return this;
     }
 
     /**
      * Removes (if found) the given transport from this {@code NetworkCapability} instance.
      *
      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void removeTransportType(int transportType) {
+    public NetworkCapabilities removeTransportType(int transportType) {
         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
             throw new IllegalArgumentException("TransportType out of range");
         }
         mTransportTypes &= ~(1 << transportType);
+        return this;
     }
 
     /**
      * Gets all the transports set on this {@code NetworkCapability} instance.
      *
-     * @return a {@link Collection} of {@code NetworkCapabilities.TRANSPORT_*} values
+     * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
      *         for this instance.
+     * @hide
      */
-    public Collection<Integer> getTransportTypes() {
+    public int[] getTransportTypes() {
         return enumerateBits(mTransportTypes);
     }
 
@@ -340,6 +356,7 @@
      * fast backhauls and slow backhauls.
      *
      * @param upKbps the estimated first hop upstream (device to network) bandwidth.
+     * @hide
      */
     public void setLinkUpstreamBandwidthKbps(int upKbps) {
         mLinkUpBandwidthKbps = upKbps;
@@ -368,6 +385,7 @@
      * fast backhauls and slow backhauls.
      *
      * @param downKbps the estimated first hop downstream (network to device) bandwidth.
+     * @hide
      */
     public void setLinkDownstreamBandwidthKbps(int downKbps) {
         mLinkDownBandwidthKbps = downKbps;
@@ -464,24 +482,22 @@
         };
 
     public String toString() {
-        Collection<Integer> types = getTransportTypes();
-        String transports = (types.size() > 0 ? " Transports: " : "");
-        Iterator<Integer> i = types.iterator();
-        while (i.hasNext()) {
-            switch (i.next()) {
+        int[] types = getTransportTypes();
+        String transports = (types.length > 0 ? " Transports: " : "");
+        for (int i = 0; i < types.length;) {
+            switch (types[i]) {
                 case TRANSPORT_CELLULAR:    transports += "CELLULAR"; break;
                 case TRANSPORT_WIFI:        transports += "WIFI"; break;
                 case TRANSPORT_BLUETOOTH:   transports += "BLUETOOTH"; break;
                 case TRANSPORT_ETHERNET:    transports += "ETHERNET"; break;
             }
-            if (i.hasNext()) transports += "|";
+            if (++i < types.length) transports += "|";
         }
 
-        types = getNetworkCapabilities();
-        String capabilities = (types.size() > 0 ? " Capabilities: " : "");
-        i = types.iterator();
-        while (i.hasNext()) {
-            switch (i.next().intValue()) {
+        types = getCapabilities();
+        String capabilities = (types.length > 0 ? " Capabilities: " : "");
+        for (int i = 0; i < types.length; ) {
+            switch (types[i]) {
                 case NET_CAPABILITY_MMS:            capabilities += "MMS"; break;
                 case NET_CAPABILITY_SUPL:           capabilities += "SUPL"; break;
                 case NET_CAPABILITY_DUN:            capabilities += "DUN"; break;
@@ -497,7 +513,7 @@
                 case NET_CAPABILITY_INTERNET:       capabilities += "INTERNET"; break;
                 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
             }
-            if (i.hasNext()) capabilities += "&";
+            if (++i < types.length) capabilities += "&";
         }
 
         String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 47377e9..36dc573 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -22,19 +22,14 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * Defines a request for a network, made by calling {@link ConnectivityManager#requestNetwork}
- * or {@link ConnectivityManager#listenForNetwork}.
- *
- * This token records the {@link NetworkCapabilities} used to make the request and identifies
- * the request.  It should be used to release the request via
- * {@link ConnectivityManager#releaseNetworkRequest} when the network is no longer desired.
+ * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
+ * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
+ * via {@link ConnectivityManager#registerNetworkCallback}.
  */
 public class NetworkRequest implements Parcelable {
     /**
-     * The {@link NetworkCapabilities} that define this request.  This should not be modified.
-     * The networkCapabilities of the request are set when
-     * {@link ConnectivityManager#requestNetwork} is called and the value is presented here
-     * as a convenient reminder of what was requested.
+     * The {@link NetworkCapabilities} that define this request.
+     * @hide
      */
     public final NetworkCapabilities networkCapabilities;
 
@@ -71,6 +66,95 @@
         this.legacyType = that.legacyType;
     }
 
+    /**
+     * Builder used to create {@link NetworkRequest} objects.  Specify the Network features
+     * needed in terms of {@link NetworkCapabilities} features
+     */
+    public static class Builder {
+        private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
+
+        /**
+         * Default constructor for Builder.
+         */
+        public Builder() {}
+
+        /**
+         * Build {@link NetworkRequest} give the current set of capabilities.
+         */
+        public NetworkRequest build() {
+            return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
+                    ConnectivityManager.REQUEST_ID_UNSET);
+        }
+
+        /**
+         * Add the given capability requirement to this builder.  These represent
+         * the requested network's required capabilities.  Note that when searching
+         * for a network to satisfy a request, all capabilities requested must be
+         * satisfied.  See {@link NetworkCapabilities} for {@code NET_CAPABILITIY_*}
+         * definitions.
+         *
+         * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
+         * @return The builder to facilitate chaining
+         *         {@code builder.addCapability(...).addCapability();}.
+         */
+        public Builder addCapability(int capability) {
+            mNetworkCapabilities.addCapability(capability);
+            return this;
+        }
+
+        /**
+         * Removes (if found) the given capability from this builder instance.
+         *
+         * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
+         * @return The builder to facilitate chaining.
+         */
+        public Builder removeCapability(int capability) {
+            mNetworkCapabilities.removeCapability(capability);
+            return this;
+        }
+
+        /**
+         * Adds the given transport requirement to this builder.  These represent
+         * the set of allowed transports for the request.  Only networks using one
+         * of these transports will satisfy the request.  If no particular transports
+         * are required, none should be specified here.  See {@link NetworkCapabilities}
+         * for {@code TRANSPORT_*} definitions.
+         *
+         * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
+         * @return The builder to facilitate chaining.
+         */
+        public Builder addTransportType(int transportType) {
+            mNetworkCapabilities.addTransportType(transportType);
+            return this;
+        }
+
+        /**
+         * Removes (if found) the given transport from this builder instance.
+         *
+         * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
+         * @return The builder to facilitate chaining.
+         */
+        public Builder removeTransportType(int transportType) {
+            mNetworkCapabilities.removeTransportType(transportType);
+            return this;
+        }
+
+        /**
+         * @hide
+         */
+        public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
+            mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
+            return this;
+        }
+        /**
+         * @hide
+         */
+        public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
+            mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
+            return this;
+        }
+    }
+
     // implement the Parcelable interface
     public int describeContents() {
         return 0;
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index edb3286..b02f88e 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -111,7 +111,7 @@
     /**
      * Binds the current process to the network designated by {@code netId}.  All sockets created
      * in the future (and not explicitly bound via a bound {@link SocketFactory} (see
-     * {@link Network#socketFactory}) will be bound to this network.  Note that if this
+     * {@link Network#getSocketFactory}) will be bound to this network.  Note that if this
      * {@code Network} ever disconnects all sockets created in this way will cease to work.  This
      * is by design so an application doesn't accidentally use sockets it thinks are still bound to
      * a particular {@code Network}.
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index 4973b3d..573a8f8 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -107,8 +107,8 @@
         mNetworkCapabilities = new NetworkCapabilities();
         mNetworkInfo.setIsAvailable(true);
         try {
-          mLinkProperties.addDns(InetAddress.getByName(DNS1));
-          mLinkProperties.addDns(InetAddress.getByName(DNS2));
+          mLinkProperties.addDnsServer(InetAddress.getByName(DNS1));
+          mLinkProperties.addDnsServer(InetAddress.getByName(DNS2));
         } catch (UnknownHostException e) {
           Log.e(TAG, "Could not add DNS address", e);
         }
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index ad8e4f7..c2b888c 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -35,10 +35,10 @@
  *
  * A route contains three pieces of information:
  * <ul>
- * <li>a destination {@link LinkAddress} for directly-connected subnets.  If this is
- *     {@code null} it indicates a default route of the address family (IPv4 or IPv6)
+ * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route.
+ *     If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6)
  *     implied by the gateway IP address.
- * <li>a gateway {@link InetAddress} for default routes.  If this is {@code null} it
+ * <li>a gateway {@link InetAddress} indicating the next hop to use.  If this is {@code null} it
  *     indicates a directly-connected route.
  * <li>an interface (which may be unspecified).
  * </ul>
@@ -46,9 +46,10 @@
  * destination and gateway are both specified, they must be of the same address family
  * (IPv4 or IPv6).
  */
-public class RouteInfo implements Parcelable {
+public final class RouteInfo implements Parcelable {
     /**
      * The IP destination address for this route.
+     * TODO: Make this an IpPrefix.
      */
     private final LinkAddress mDestination;
 
@@ -80,6 +81,19 @@
      * @param destination the destination prefix
      * @param gateway the IP address to route packets through
      * @param iface the interface name to send packets on
+     *
+     * TODO: Convert to use IpPrefix.
+     *
+     * @hide
+     */
+    public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
+        this(destination == null ? null :
+                new LinkAddress(destination.getAddress(), destination.getPrefixLength()),
+                gateway, iface);
+    }
+
+    /**
+     * @hide
      */
     public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
         if (destination == null) {
@@ -105,7 +119,7 @@
         mHasGateway = (!gateway.isAnyLocalAddress());
 
         mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
-                destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength());
+                destination.getPrefixLength()), destination.getPrefixLength());
         if ((destination.getAddress() instanceof Inet4Address &&
                  (gateway instanceof Inet4Address == false)) ||
                 (destination.getAddress() instanceof Inet6Address &&
@@ -128,8 +142,17 @@
      * <p>
      * Destination and gateway may not both be null.
      *
-     * @param destination the destination address and prefix in a {@link LinkAddress}
+     * @param destination the destination address and prefix in an {@link IpPrefix}
      * @param gateway the {@link InetAddress} to route packets through
+     *
+     * @hide
+     */
+    public RouteInfo(IpPrefix destination, InetAddress gateway) {
+        this(destination, gateway, null);
+    }
+
+    /**
+     * @hide
      */
     public RouteInfo(LinkAddress destination, InetAddress gateway) {
         this(destination, gateway, null);
@@ -139,16 +162,27 @@
      * Constructs a default {@code RouteInfo} object.
      *
      * @param gateway the {@link InetAddress} to route packets through
+     *
+     * @hide
      */
     public RouteInfo(InetAddress gateway) {
-        this(null, gateway, null);
+        this((LinkAddress) null, gateway, null);
     }
 
     /**
      * Constructs a {@code RouteInfo} object representing a direct connected subnet.
      *
-     * @param destination the {@link LinkAddress} describing the address and prefix
+     * @param destination the {@link IpPrefix} describing the address and prefix
      *                    length of the subnet.
+     *
+     * @hide
+     */
+    public RouteInfo(IpPrefix destination) {
+        this(destination, null, null);
+    }
+
+    /**
+     * @hide
      */
     public RouteInfo(LinkAddress destination) {
         this(destination, null, null);
@@ -176,29 +210,37 @@
 
     private boolean isHost() {
         return (mDestination.getAddress() instanceof Inet4Address &&
-                mDestination.getNetworkPrefixLength() == 32) ||
+                mDestination.getPrefixLength() == 32) ||
                (mDestination.getAddress() instanceof Inet6Address &&
-                mDestination.getNetworkPrefixLength() == 128);
+                mDestination.getPrefixLength() == 128);
     }
 
     private boolean isDefault() {
         boolean val = false;
         if (mGateway != null) {
             if (mGateway instanceof Inet4Address) {
-                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
+                val = (mDestination == null || mDestination.getPrefixLength() == 0);
             } else {
-                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
+                val = (mDestination == null || mDestination.getPrefixLength() == 0);
             }
         }
         return val;
     }
 
     /**
-     * Retrieves the destination address and prefix length in the form of a {@link LinkAddress}.
+     * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}.
      *
-     * @return {@link LinkAddress} specifying the destination.  This is never {@code null}.
+     * @return {@link IpPrefix} specifying the destination.  This is never {@code null}.
      */
-    public LinkAddress getDestination() {
+    public IpPrefix getDestination() {
+        return new IpPrefix(mDestination.getAddress(), mDestination.getPrefixLength());
+    }
+
+    /**
+     * TODO: Convert callers to use IpPrefix and then remove.
+     * @hide
+     */
+    public LinkAddress getDestinationLinkAddress() {
         return mDestination;
     }
 
@@ -233,7 +275,8 @@
     /**
      * Indicates if this route is a host route (ie, matches only a single host address).
      *
-     * @return {@code true} if the destination has a prefix length of 32/128 for v4/v6.
+     * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6,
+     * respectively.
      * @hide
      */
     public boolean isHostRoute() {
@@ -263,7 +306,7 @@
 
         // match the route destination and destination with prefix length
         InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
-                mDestination.getNetworkPrefixLength());
+                mDestination.getPrefixLength());
 
         return mDestination.getAddress().equals(dstNet);
     }
@@ -285,8 +328,8 @@
         for (RouteInfo route : routes) {
             if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
                 if ((bestRoute != null) &&
-                        (bestRoute.mDestination.getNetworkPrefixLength() >=
-                        route.mDestination.getNetworkPrefixLength())) {
+                        (bestRoute.mDestination.getPrefixLength() >=
+                        route.mDestination.getPrefixLength())) {
                     continue;
                 }
                 if (route.matches(dest)) bestRoute = route;
@@ -295,13 +338,22 @@
         return bestRoute;
     }
 
+    /**
+     * Returns a human-readable description of this object.
+     */
     public String toString() {
         String val = "";
         if (mDestination != null) val = mDestination.toString();
-        if (mGateway != null) val += " -> " + mGateway.getHostAddress();
+        val += " ->";
+        if (mGateway != null) val += " " + mGateway.getHostAddress();
+        if (mInterface != null) val += " " + mInterface;
         return val;
     }
 
+    /**
+     * Compares this RouteInfo object against the specified object and indicates if they are equal.
+     * @return {@code true} if the objects are equal, {@code false} otherwise.
+     */
     public boolean equals(Object obj) {
         if (this == obj) return true;
 
@@ -309,11 +361,14 @@
 
         RouteInfo target = (RouteInfo) obj;
 
-        return Objects.equals(mDestination, target.getDestination()) &&
+        return Objects.equals(mDestination, target.getDestinationLinkAddress()) &&
                 Objects.equals(mGateway, target.getGateway()) &&
                 Objects.equals(mInterface, target.getInterface());
     }
 
+    /**
+     *  Returns a hashcode for this <code>RouteInfo</code> object.
+     */
     public int hashCode() {
         return (mDestination == null ? 0 : mDestination.hashCode() * 41)
                 + (mGateway == null ? 0 :mGateway.hashCode() * 47)
@@ -323,7 +378,6 @@
 
     /**
      * Implement the Parcelable interface
-     * @hide
      */
     public int describeContents() {
         return 0;
@@ -331,7 +385,6 @@
 
     /**
      * Implement the Parcelable interface
-     * @hide
      */
     public void writeToParcel(Parcel dest, int flags) {
         if (mDestination == null) {
@@ -339,7 +392,7 @@
         } else {
             dest.writeByte((byte) 1);
             dest.writeByteArray(mDestination.getAddress().getAddress());
-            dest.writeInt(mDestination.getNetworkPrefixLength());
+            dest.writeInt(mDestination.getPrefixLength());
         }
 
         if (mGateway == null) {
@@ -354,7 +407,6 @@
 
     /**
      * Implement the Parcelable interface.
-     * @hide
      */
     public static final Creator<RouteInfo> CREATOR =
         new Creator<RouteInfo>() {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e9ffc52..55c66ba 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -791,6 +791,15 @@
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_PAIRING_SETTINGS = "android.settings.PAIRING_SETTINGS";
 
+    /**
+     * Activity Action: Show battery saver settings.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_BATTERY_SAVER_SETTINGS
+            = "android.settings.BATTERY_SAVER_SETTINGS";
+
     // End of Intent actions for Settings
 
     /**
@@ -6018,6 +6027,13 @@
          */
         public static final String LOW_POWER_MODE = "low_power";
 
+        /**
+         * Battery level [1-99] at which low power mode automatically turns on.
+         * If 0, it will not automatically turn on.
+         * @hide
+         */
+        public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
+
          /**
          * If 1, the activity manager will aggressively finish activities and
          * processes as soon as they are no longer needed.  If 0, the normal
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index fd475cd..8bd0f4d 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -29,6 +29,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import java.util.List;
@@ -54,7 +55,7 @@
             + "[" + getClass().getSimpleName() + "]";
 
     private INotificationListenerWrapper mWrapper = null;
-    private Ranking mRanking;
+    private RankingMap mRankingMap;
 
     private INotificationManager mNoMan;
 
@@ -75,7 +76,22 @@
      *            object as well as its identifying information (tag and id) and source
      *            (package name).
      */
-    public abstract void onNotificationPosted(StatusBarNotification sbn);
+    public void onNotificationPosted(StatusBarNotification sbn) {
+        // optional
+    }
+
+    /**
+     * Implement this method to learn about new notifications as they are posted by apps.
+     *
+     * @param sbn A data structure encapsulating the original {@link android.app.Notification}
+     *            object as well as its identifying information (tag and id) and source
+     *            (package name).
+     * @param rankingMap The current ranking map that can be used to retrieve ranking information
+     *                   for active notifications, including the newly posted one.
+     */
+    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+        onNotificationPosted(sbn);
+    }
 
     /**
      * Implement this method to learn when notifications are removed.
@@ -94,7 +110,33 @@
      *            and source (package name) used to post the {@link android.app.Notification} that
      *            was just removed.
      */
-    public abstract void onNotificationRemoved(StatusBarNotification sbn);
+    public void onNotificationRemoved(StatusBarNotification sbn) {
+        // optional
+    }
+
+    /**
+     * Implement this method to learn when notifications are removed.
+     * <P>
+     * This might occur because the user has dismissed the notification using system UI (or another
+     * notification listener) or because the app has withdrawn the notification.
+     * <P>
+     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
+     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
+     * fields such as {@link android.app.Notification#contentView} and
+     * {@link android.app.Notification#largeIcon}. However, all other fields on
+     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
+     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
+     *
+     * @param sbn A data structure encapsulating at least the original information (tag and id)
+     *            and source (package name) used to post the {@link android.app.Notification} that
+     *            was just removed.
+     * @param rankingMap The current ranking map that can be used to retrieve ranking information
+     *                   for active notifications.
+     *
+     */
+    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+        onNotificationRemoved(sbn);
+    }
 
     /**
      * Implement this method to learn about when the listener is enabled and connected to
@@ -107,10 +149,11 @@
 
     /**
      * Implement this method to be notified when the notification ranking changes.
-     * <P>
-     * Call {@link #getCurrentRanking()} to retrieve the new ranking.
+     *
+     * @param rankingMap The current ranking map that can be used to retrieve ranking information
+     *                   for active notifications.
      */
-    public void onNotificationRankingUpdate() {
+    public void onNotificationRankingUpdate(RankingMap rankingMap) {
         // optional
     }
 
@@ -241,16 +284,19 @@
      *
      * <p>
      * The returned object represents the current ranking snapshot and only
-     * applies for currently active notifications. Hence you must retrieve a
-     * new Ranking after each notification event such as
-     * {@link #onNotificationPosted(StatusBarNotification)},
-     * {@link #onNotificationRemoved(StatusBarNotification)}, etc.
+     * applies for currently active notifications.
+     * <p>
+     * Generally you should use the RankingMap that is passed with events such
+     * as {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
+     * {@link #onNotificationRemoved(StatusBarNotification, RankingMap)}, and
+     * so on. This method should only be used when needing access outside of
+     * such events, for example to retrieve the RankingMap right after
+     * initialization.
      *
-     * @return A {@link NotificationListenerService.Ranking} object providing
-     *     access to ranking information
+     * @return A {@link RankingMap} object providing access to ranking information
      */
-    public Ranking getCurrentRanking() {
-        return mRanking;
+    public RankingMap getCurrentRanking() {
+        return mRankingMap;
     }
 
     @Override
@@ -313,7 +359,7 @@
             synchronized (mWrapper) {
                 applyUpdate(update);
                 try {
-                    NotificationListenerService.this.onNotificationPosted(sbn);
+                    NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
                 } catch (Throwable t) {
                     Log.w(TAG, "Error running onNotificationPosted", t);
                 }
@@ -326,7 +372,7 @@
             synchronized (mWrapper) {
                 applyUpdate(update);
                 try {
-                    NotificationListenerService.this.onNotificationRemoved(sbn);
+                    NotificationListenerService.this.onNotificationRemoved(sbn, mRankingMap);
                 } catch (Throwable t) {
                     Log.w(TAG, "Error running onNotificationRemoved", t);
                 }
@@ -351,7 +397,7 @@
             synchronized (mWrapper) {
                 applyUpdate(update);
                 try {
-                    NotificationListenerService.this.onNotificationRankingUpdate();
+                    NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
                 } catch (Throwable t) {
                     Log.w(TAG, "Error running onNotificationRankingUpdate", t);
                 }
@@ -360,7 +406,65 @@
     }
 
     private void applyUpdate(NotificationRankingUpdate update) {
-        mRanking = new Ranking(update);
+        mRankingMap = new RankingMap(update);
+    }
+
+    /**
+     * Provides access to ranking information on a currently active
+     * notification.
+     *
+     * <p>
+     * Note that this object is not updated on notification events (such as
+     * {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
+     * {@link #onNotificationRemoved(StatusBarNotification)}, etc.). Make sure
+     * to retrieve a new Ranking from the current {@link RankingMap} whenever
+     * a notification event occurs.
+     */
+    public static class Ranking {
+        private final String mKey;
+        private final int mRank;
+        private final boolean mIsAmbient;
+        private final boolean mIsInterceptedByDnd;
+
+        private Ranking(String key, int rank, boolean isAmbient, boolean isInterceptedByDnd) {
+            mKey = key;
+            mRank = rank;
+            mIsAmbient = isAmbient;
+            mIsInterceptedByDnd = isInterceptedByDnd;
+        }
+
+        /**
+         * Returns the key of the notification this Ranking applies to.
+         */
+        public String getKey() {
+            return mKey;
+        }
+
+        /**
+         * Returns the rank of the notification.
+         *
+         * @return the rank of the notification, that is the 0-based index in
+         *     the list of active notifications.
+         */
+        public int getRank() {
+            return mRank;
+        }
+
+        /**
+         * Returns whether the notification is an ambient notification, that is
+         * a notification that doesn't require the user's immediate attention.
+         */
+        public boolean isAmbient() {
+            return mIsAmbient;
+        }
+
+        /**
+         * Returns whether the notification was intercepted by
+         * &quot;Do not disturb&quot;.
+         */
+        public boolean isInterceptedByDoNotDisturb() {
+            return mIsInterceptedByDnd;
+        }
     }
 
     /**
@@ -371,11 +475,14 @@
      * Note that this object represents a ranking snapshot that only applies to
      * notifications active at the time of retrieval.
      */
-    public static class Ranking implements Parcelable {
+    public static class RankingMap implements Parcelable {
         private final NotificationRankingUpdate mRankingUpdate;
+        private final ArrayMap<String, Ranking> mRankingCache;
+        private boolean mRankingCacheInitialized;
 
-        private Ranking(NotificationRankingUpdate rankingUpdate) {
+        private RankingMap(NotificationRankingUpdate rankingUpdate) {
             mRankingUpdate = rankingUpdate;
+            mRankingCache = new ArrayMap<>(rankingUpdate.getOrderedKeys().length);
         }
 
         /**
@@ -389,56 +496,37 @@
         }
 
         /**
-         * Returns the rank of the notification with the given key, that is the
-         * index of <code>key</code> in the array of keys returned by
-         * {@link #getOrderedKeys()}.
+         * Returns the Ranking for the notification with the given key.
          *
-         * @return The rank of the notification with the given key; -1 when the
-         *      given key is unknown.
+         * @return the Ranking of the notification with the given key;
+         *     <code>null</code> when the key is unknown.
          */
-        public int getRank(String key) {
-            // TODO: Optimize.
+        public Ranking getRanking(String key) {
+            synchronized (mRankingCache) {
+                if (!mRankingCacheInitialized) {
+                    initializeRankingCache();
+                    mRankingCacheInitialized = true;
+                }
+            }
+            return mRankingCache.get(key);
+        }
+
+        private void initializeRankingCache() {
             String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            for (int i = 0; i < orderedKeys.length; i++) {
-                if (orderedKeys[i].equals(key)) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        /**
-         * Returns whether the notification with the given key was intercepted
-         * by &quot;Do not disturb&quot;.
-         */
-        public boolean isInterceptedByDoNotDisturb(String key) {
-            // TODO: Optimize.
-            for (String interceptedKey : mRankingUpdate.getDndInterceptedKeys()) {
-                if (interceptedKey.equals(key)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Returns whether the notification with the given key is an ambient
-         * notification, that is a notification that doesn't require the user's
-         * immediate attention.
-         */
-        public boolean isAmbient(String key) {
-            // TODO: Optimize.
             int firstAmbientIndex = mRankingUpdate.getFirstAmbientIndex();
-            if (firstAmbientIndex < 0) {
-                return false;
-            }
-            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            for (int i = firstAmbientIndex; i < orderedKeys.length; i++) {
-                if (orderedKeys[i].equals(key)) {
-                    return true;
+            for (int i = 0; i < orderedKeys.length; i++) {
+                String key = orderedKeys[i];
+                boolean isAmbient = firstAmbientIndex > -1 && firstAmbientIndex <= i;
+                boolean isInterceptedByDnd = false;
+                // TODO: Optimize.
+                for (String s : mRankingUpdate.getDndInterceptedKeys()) {
+                    if (s.equals(key)) {
+                        isInterceptedByDnd = true;
+                        break;
+                    }
                 }
+                mRankingCache.put(key, new Ranking(key, i, isAmbient, isInterceptedByDnd));
             }
-            return false;
         }
 
         // ----------- Parcelable
@@ -453,16 +541,16 @@
             dest.writeParcelable(mRankingUpdate, flags);
         }
 
-        public static final Creator<Ranking> CREATOR = new Creator<Ranking>() {
+        public static final Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
             @Override
-            public Ranking createFromParcel(Parcel source) {
+            public RankingMap createFromParcel(Parcel source) {
                 NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
-                return new Ranking(rankingUpdate);
+                return new RankingMap(rankingUpdate);
             }
 
             @Override
-            public Ranking[] newArray(int size) {
-                return new Ranking[size];
+            public RankingMap[] newArray(int size) {
+                return new RankingMap[size];
             }
         };
     }
diff --git a/core/java/android/speech/tts/RequestConfig.java b/core/java/android/speech/tts/RequestConfig.java
index 4b5385f..72109d3 100644
--- a/core/java/android/speech/tts/RequestConfig.java
+++ b/core/java/android/speech/tts/RequestConfig.java
@@ -8,6 +8,7 @@
  *
  * This class is immutable, and can only be constructed using
  * {@link RequestConfig.Builder}.
+ * @hide
  */
 public final class RequestConfig {
 
diff --git a/core/java/android/speech/tts/RequestConfigHelper.java b/core/java/android/speech/tts/RequestConfigHelper.java
index b25c985..2e548af 100644
--- a/core/java/android/speech/tts/RequestConfigHelper.java
+++ b/core/java/android/speech/tts/RequestConfigHelper.java
@@ -7,6 +7,7 @@
 /**
  * Set of common heuristics for selecting {@link VoiceInfo} from
  * {@link TextToSpeechClient#getEngineStatus()} output.
+ * @hide
  */
 public final class RequestConfigHelper {
     private RequestConfigHelper() {}
diff --git a/core/java/android/speech/tts/SynthesisCallback.java b/core/java/android/speech/tts/SynthesisCallback.java
index bc2f239..7b319b7 100644
--- a/core/java/android/speech/tts/SynthesisCallback.java
+++ b/core/java/android/speech/tts/SynthesisCallback.java
@@ -43,16 +43,13 @@
      * request.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText} or
-     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     * while in {@link TextToSpeechService#onSynthesizeText}.
      *
      * @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}, {@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);
 
@@ -60,8 +57,7 @@
      * 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} or
-     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     * while in {@link TextToSpeechService#onSynthesizeText}.
      *
      * @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.
@@ -69,8 +65,6 @@
      * @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);
 
@@ -79,14 +73,11 @@
      * been passed to {@link #audioAvailable}.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText} or
-     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     * while in {@link TextToSpeechService#onSynthesizeText}.
      *
      * 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();
 
@@ -108,6 +99,7 @@
      *
      * @param errorCode Error code to pass to the client. One of the ERROR_ values from
      *      {@link TextToSpeechClient.Status}
+     * @hide
      */
     public void error(int errorCode);
 
@@ -128,6 +120,7 @@
      * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} if client already
      *          called {@link #start(int, int, int)}, {@link TextToSpeechClient.Status#STOPPED}
      *          if stop was requested.
+     * @hide
      */
     public int fallback();
 
@@ -139,6 +132,7 @@
      * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
      * Useful for checking if a fallback from network request is possible.
+     * @hide
      */
     public boolean hasStarted();
 
@@ -150,6 +144,7 @@
      * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
      * Useful for checking if a fallback from network request is possible.
+     * @hide
      */
     public boolean hasFinished();
 }
diff --git a/core/java/android/speech/tts/SynthesisRequestV2.java b/core/java/android/speech/tts/SynthesisRequestV2.java
index a1da49c..beb7307 100644
--- a/core/java/android/speech/tts/SynthesisRequestV2.java
+++ b/core/java/android/speech/tts/SynthesisRequestV2.java
@@ -14,6 +14,7 @@
  *   <li>Voice parameters (Bundle of parameters)</li>
  *   <li>Audio parameters (Bundle of parameters)</li>
  * </ul>
+ * @hide
  */
 public final class SynthesisRequestV2 implements Parcelable {
     /** Synthesis utterance. */
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index c527acf..cc86ed7 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -53,10 +53,7 @@
  * notified of the completion of the initialization.<br>
  * 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";
diff --git a/core/java/android/speech/tts/TextToSpeechClient.java b/core/java/android/speech/tts/TextToSpeechClient.java
index 85f702b..2a24229 100644
--- a/core/java/android/speech/tts/TextToSpeechClient.java
+++ b/core/java/android/speech/tts/TextToSpeechClient.java
@@ -71,6 +71,7 @@
  * 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.
+ * @hide
  */
 public class TextToSpeechClient {
     private static final String TAG = TextToSpeechClient.class.getSimpleName();
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 6b899d9..a728472 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -74,26 +74,6 @@
  *
  * {@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 {
 
@@ -245,6 +225,7 @@
      * 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.
+     * @hide
      */
     protected List<VoiceInfo> checkVoicesInfo() {
         if (implementsV2API()) {
@@ -312,6 +293,7 @@
      * 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.
+     * @hide
      */
     protected void onVoicesInfoChange() {
 
@@ -326,6 +308,7 @@
      * @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.
+     * @hide
      */
     protected void onSynthesizeTextV2(SynthesisRequestV2 request,
             VoiceInfo selectedVoice,
@@ -367,6 +350,7 @@
     /**
      * If true, this service implements proper V2 TTS API service. If it's false,
      * V2 API will be provided through adapter.
+     * @hide
      */
     protected boolean implementsV2API() {
         return false;
@@ -405,6 +389,9 @@
         }
     }
 
+   /**
+    * @hide
+    */
     public VoiceInfo getVoicesInfoWithName(String name) {
         synchronized (mVoicesInfoLock) {
             if (mVoicesInfoLookup != null) {
@@ -424,6 +411,7 @@
      * Use this method only if you know that set of available languages changed.
      *
      * Can be called on multiple threads.
+     * @hide
      */
     public void forceVoicesInfoCheck() {
         synchronized (mVoicesInfoLock) {
diff --git a/core/java/android/speech/tts/VoiceInfo.java b/core/java/android/speech/tts/VoiceInfo.java
index 16b9a97..57cb615 100644
--- a/core/java/android/speech/tts/VoiceInfo.java
+++ b/core/java/android/speech/tts/VoiceInfo.java
@@ -16,6 +16,7 @@
  * 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.
+ * @hide
  */
 public final class VoiceInfo implements Parcelable {
     /** Very low, but still intelligible quality of speech synthesis */
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index f440853..1d9aa05 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -440,26 +440,10 @@
     }
 
     // Documentation from interface
-    public SpannableStringBuilder replace(int start, int end,
+    public SpannableStringBuilder replace(final int start, final 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);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 11db996..72b9d3e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -74,7 +74,8 @@
     private boolean mProfilingEnabled;
 
     ThreadedRenderer(boolean translucent) {
-        AtlasInitializer.sInstance.init();
+        // Temporarily disabled
+        //AtlasInitializer.sInstance.init();
 
         long rootNodePtr = nCreateRootRenderNode();
         mRootNode = RenderNode.adopt(rootNodePtr);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 117fe8e..7c70ee4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6105,7 +6105,7 @@
             // apply insets path and take things from there.
             try {
                 mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
-                return !dispatchApplyWindowInsets(new WindowInsets(insets)).hasInsets();
+                return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
             } finally {
                 mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
             }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0f40ee7..eef09ae 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5574,11 +5574,11 @@
     @Override
     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
         insets = super.dispatchApplyWindowInsets(insets);
-        if (insets.hasInsets()) {
+        if (!insets.isConsumed()) {
             final int count = getChildCount();
             for (int i = 0; i < count; i++) {
                 insets = getChildAt(i).dispatchApplyWindowInsets(insets);
-                if (!insets.hasInsets()) {
+                if (insets.isConsumed()) {
                     break;
                 }
             }
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 294f472..9b75595 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -35,6 +35,9 @@
     private Rect mTempRect;
     private boolean mIsRound;
 
+    private boolean mSystemWindowInsetsConsumed = false;
+    private boolean mWindowDecorInsetsConsumed = false;
+
     private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
 
     /**
@@ -43,7 +46,13 @@
      * 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);
+    public static final WindowInsets CONSUMED;
+
+    static {
+        CONSUMED = new WindowInsets(EMPTY_RECT, EMPTY_RECT);
+        CONSUMED.mSystemWindowInsetsConsumed = true;
+        CONSUMED.mWindowDecorInsetsConsumed = true;
+    }
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets) {
@@ -52,13 +61,17 @@
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets, boolean isRound) {
-        this(systemWindowInsets, EMPTY_RECT, isRound);
+        this(systemWindowInsets, null, isRound);
     }
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, boolean isRound) {
-        mSystemWindowInsets = systemWindowInsets;
-        mWindowDecorInsets = windowDecorInsets;
+        mSystemWindowInsetsConsumed = systemWindowInsets == null;
+        mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets;
+
+        mWindowDecorInsetsConsumed = windowDecorInsets == null;
+        mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : windowDecorInsets;
+
         mIsRound = isRound;
     }
 
@@ -70,12 +83,14 @@
     public WindowInsets(WindowInsets src) {
         mSystemWindowInsets = src.mSystemWindowInsets;
         mWindowDecorInsets = src.mWindowDecorInsets;
+        mSystemWindowInsetsConsumed = src.mSystemWindowInsetsConsumed;
+        mWindowDecorInsetsConsumed = src.mWindowDecorInsetsConsumed;
         mIsRound = src.mIsRound;
     }
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets) {
-        this(systemWindowInsets, EMPTY_RECT);
+        this(systemWindowInsets, null);
     }
 
     /**
@@ -238,6 +253,24 @@
     }
 
     /**
+     * Check if these insets have been fully consumed.
+     *
+     * <p>Insets are considered "consumed" if the applicable <code>consume*</code> methods
+     * have been called such that all insets have been set to zero. This affects propagation of
+     * insets through the view hierarchy; insets that have not been fully consumed will continue
+     * to propagate down to child views.</p>
+     *
+     * <p>The result of this method is equivalent to the return value of
+     * {@link View#fitSystemWindows(android.graphics.Rect)}.</p>
+     *
+     * @return true if the insets have been fully consumed.
+     * @hide Pending API
+     */
+    public boolean isConsumed() {
+        return mSystemWindowInsetsConsumed && mWindowDecorInsetsConsumed;
+    }
+
+    /**
      * Returns true if the associated window has a round shape.
      *
      * <p>A round window's left, top, right and bottom edges reach all the way to the
@@ -258,7 +291,8 @@
      */
     public WindowInsets consumeSystemWindowInsets() {
         final WindowInsets result = new WindowInsets(this);
-        result.mSystemWindowInsets = new Rect(0, 0, 0, 0);
+        result.mSystemWindowInsets = EMPTY_RECT;
+        result.mSystemWindowInsetsConsumed = true;
         return result;
     }
 
@@ -276,10 +310,12 @@
             boolean right, boolean bottom) {
         if (left || top || right || bottom) {
             final WindowInsets result = new WindowInsets(this);
-            result.mSystemWindowInsets = new Rect(left ? 0 : mSystemWindowInsets.left,
+            result.mSystemWindowInsets = new Rect(
+                    left ? 0 : mSystemWindowInsets.left,
                     top ? 0 : mSystemWindowInsets.top,
                     right ? 0 : mSystemWindowInsets.right,
                     bottom ? 0 : mSystemWindowInsets.bottom);
+            result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
             return result;
         }
         return this;
@@ -299,6 +335,7 @@
             int right, int bottom) {
         final WindowInsets result = new WindowInsets(this);
         result.mSystemWindowInsets = new Rect(left, top, right, bottom);
+        result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
         return result;
     }
 
@@ -308,6 +345,7 @@
     public WindowInsets consumeWindowDecorInsets() {
         final WindowInsets result = new WindowInsets(this);
         result.mWindowDecorInsets.set(0, 0, 0, 0);
+        result.mWindowDecorInsetsConsumed = true;
         return result;
     }
 
@@ -322,6 +360,7 @@
                     top ? 0 : mWindowDecorInsets.top,
                     right ? 0 : mWindowDecorInsets.right,
                     bottom ? 0 : mWindowDecorInsets.bottom);
+            result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
             return result;
         }
         return this;
@@ -333,6 +372,7 @@
     public WindowInsets replaceWindowDecorInsets(int left, int top, int right, int bottom) {
         final WindowInsets result = new WindowInsets(this);
         result.mWindowDecorInsets = new Rect(left, top, right, bottom);
+        result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
         return result;
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 5b9372d..4748402 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -225,17 +225,11 @@
         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();
+                // The system is just sending data for windows that we introspected
+                // and changed but not ones that appeared, so we have to always call
+                // into the system process. This is less expensice as opposed to
+                // sending all windows on every window change.
+                List<AccessibilityWindowInfo> windows = connection.getWindows();
                 if (windows != null) {
                     final int windowCount = windows.size();
                     for (int i = 0; i < windowCount; i++) {
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index fad6747..66f5f6c 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -186,12 +186,12 @@
     /**
      * Builder for {@link CursorAnchorInfo}. This class is not designed to be thread-safe.
      */
-    public static final class CursorAnchorInfoBuilder {
+    public static final class Builder {
         /**
          * Sets the text range of the selection. Calling this can be skipped if there is no
          * selection.
          */
-        public CursorAnchorInfoBuilder setSelectionRange(final int newStart, final int newEnd) {
+        public Builder setSelectionRange(final int newStart, final int newEnd) {
             mSelectionStart = newStart;
             mSelectionEnd = newEnd;
             return this;
@@ -205,8 +205,7 @@
          * @param index index where the composing text starts.
          * @param composingText the entire composing text.
          */
-        public CursorAnchorInfoBuilder setComposingText(final int index,
-                final CharSequence composingText) {
+        public Builder setComposingText(final int index, final CharSequence composingText) {
             mComposingTextStart = index;
             if (composingText == null) {
                 mComposingText = null;
@@ -236,9 +235,8 @@
          * that will be transformed with the transformation matrix when rendered on the screen. This
          * should be calculated or compatible with {@link Layout#getLineBottom(int)}.
          */
-        public CursorAnchorInfoBuilder setInsertionMarkerLocation(
-                final float horizontalPosition, final float lineTop, final float lineBaseline,
-                final float lineBottom){
+        public Builder setInsertionMarkerLocation(final float horizontalPosition,
+                final float lineTop, final float lineBaseline, final float lineBottom){
             mInsertionMarkerHorizontal = horizontalPosition;
             mInsertionMarkerTop = lineTop;
             mInsertionMarkerBaseline = lineBaseline;
@@ -269,9 +267,8 @@
          * @throws IllegalArgumentException If the index is a negative value, or not greater than
          * all of the previously called indices.
          */
-        public CursorAnchorInfoBuilder addCharacterRect(final int index,
-                final float leadingEdgeX, final float leadingEdgeY, final float trailingEdgeX,
-                final float trailingEdgeY) {
+        public Builder addCharacterRect(final int index, final float leadingEdgeX,
+                final float leadingEdgeY, final float trailingEdgeX, final float trailingEdgeY) {
             if (index < 0) {
                 throw new IllegalArgumentException("index must not be a negative integer.");
             }
@@ -289,7 +286,7 @@
          * @param matrix transformation matrix from local coordinates into screen coordinates. null
          * is interpreted as an identity matrix.
          */
-        public CursorAnchorInfoBuilder setMatrix(final Matrix matrix) {
+        public Builder setMatrix(final Matrix matrix) {
             mMatrix.set(matrix != null ? matrix : Matrix.IDENTITY_MATRIX);
             return this;
         }
@@ -297,7 +294,7 @@
 
         /**
          * @return {@link CursorAnchorInfo} using parameters in this
-         * {@link CursorAnchorInfoBuilder}.
+         * {@link Builder}.
          */
         public CursorAnchorInfo build() {
             return new CursorAnchorInfo(this);
@@ -323,7 +320,7 @@
         }
     }
 
-    private CursorAnchorInfo(final CursorAnchorInfoBuilder builder) {
+    private CursorAnchorInfo(final Builder builder) {
         mSelectionStart = builder.mSelectionStart;
         mSelectionEnd = builder.mSelectionEnd;
         mComposingTextStart = builder.mComposingTextStart;
diff --git a/core/java/android/webkit/ClientCertRequest.java b/core/java/android/webkit/ClientCertRequest.java
index 588b868..4a7f5fd 100644
--- a/core/java/android/webkit/ClientCertRequest.java
+++ b/core/java/android/webkit/ClientCertRequest.java
@@ -27,7 +27,7 @@
  * such as the host name and the port number requesting the cert, the acceptable
  * key types and the principals.
  *
- * The user should call one of the interface methods to indicate how to deal
+ * The user should call one of the class methods to indicate how to deal
  * with the client certificate request. All methods should be called on
  * UI thread.
  *
@@ -37,42 +37,45 @@
  * {@link WebView#clearClientCertPreferences}.
  *
  */
-public interface ClientCertRequest {
+public abstract class ClientCertRequest {
+
+    public ClientCertRequest() { }
+
     /**
      * Returns the acceptable types of asymmetric keys (can be null).
      */
-    public String[] getKeyTypes();
+    public abstract String[] getKeyTypes();
 
     /**
      * Returns the acceptable certificate issuers for the certificate
      *            matching the private key (can be null).
      */
-    public Principal[] getPrincipals();
+    public abstract Principal[] getPrincipals();
 
     /**
      * Returns the host name of the server requesting the certificate.
      */
-    public String getHost();
+    public abstract String getHost();
 
     /**
      * Returns the port number of the server requesting the certificate.
      */
-    public int getPort();
+    public abstract int getPort();
 
     /**
      * Proceed with the specified private key and client certificate chain.
      * Remember the user's positive choice and use it for future requests.
      */
-    public void proceed(PrivateKey privateKey, X509Certificate[] chain);
+    public abstract void proceed(PrivateKey privateKey, X509Certificate[] chain);
 
     /**
      * Ignore the request for now. Do not remember user's choice.
      */
-    public void ignore();
+    public abstract void ignore();
 
     /**
      * Cancel this request. Remember the user's choice and use it for
      * future requests.
      */
-    public void cancel();
+    public abstract void cancel();
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 91ca7b4..482c7e8 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1486,11 +1486,11 @@
     }
 
     /**
-     * Clears the client certificate preferences table stored in response
-     * to proceeding/cancelling client cert requests. Note that webview
+     * Clears the client certificate preferences stored in response
+     * to proceeding/cancelling client cert requests. Note that Webview
      * automatically clears these preferences when it receives a
-     * {@link KeyChain#ACTION_STORAGE_CHANGED} intent. The client certificate
-     * preferences are global for all Webviews.
+     * {@link KeyChain#ACTION_STORAGE_CHANGED} intent. The preferences are
+     * shared by all the webviews that are created by the embedder application.
      *
      * @param onCleared  A runnable to be invoked when client certs are cleared.
      *                   The embedder can pass null if not interested in the
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 27d6b82..4467128 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -96,7 +96,6 @@
 import android.view.WindowManager;
 import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.CursorAnchorInfo;
-import android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
@@ -3013,7 +3012,7 @@
      * {@link InputMethodManager#isWatchingCursor(View)} returns false.
      */
     private final class CursorAnchorInfoNotifier implements TextViewPositionListener {
-        final CursorAnchorInfoBuilder mSelectionInfoBuilder = new CursorAnchorInfoBuilder();
+        final CursorAnchorInfo.Builder mSelectionInfoBuilder = new CursorAnchorInfo.Builder();
         final int[] mTmpIntOffset = new int[2];
         final Matrix mViewToScreenMatrix = new Matrix();
 
@@ -3037,7 +3036,7 @@
                 return;
             }
 
-            final CursorAnchorInfoBuilder builder = mSelectionInfoBuilder;
+            final CursorAnchorInfo.Builder builder = mSelectionInfoBuilder;
             builder.reset();
 
             final int selectionStart = mTextView.getSelectionStart();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 43c8dde..84202eb 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5842,7 +5842,6 @@
                 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);
             }
         }
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index cbd9a6a..4f1cd68 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -146,6 +146,8 @@
     private ActionMenuPresenter mOuterActionMenuPresenter;
     private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
 
+    private boolean mCollapsible;
+
     public Toolbar(Context context) {
         this(context, null);
     }
@@ -969,6 +971,23 @@
         return child.getMeasuredWidth() + hMargins;
     }
 
+    /**
+     * Returns true if the Toolbar is collapsible and has no child views with a measured size > 0.
+     */
+    private boolean shouldCollapse() {
+        if (!mCollapsible) return false;
+
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (shouldLayout(child) && child.getMeasuredWidth() > 0 &&
+                    child.getMeasuredHeight() > 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int width = 0;
@@ -1093,7 +1112,8 @@
         final int measuredHeight = resolveSizeAndState(
                 Math.max(height, getSuggestedMinimumHeight()),
                 heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT);
-        setMeasuredDimension(measuredWidth, measuredHeight);
+
+        setMeasuredDimension(measuredWidth, shouldCollapse() ? 0 : measuredHeight);
     }
 
     @Override
@@ -1490,6 +1510,16 @@
     }
 
     /**
+     * Force the toolbar to collapse to zero-height during measurement if
+     * it could be considered "empty" (no visible elements with nonzero measured size)
+     * @hide
+     */
+    public void setCollapsible(boolean collapsible) {
+        mCollapsible = collapsible;
+        requestLayout();
+    }
+
+    /**
      * Interface responsible for receiving menu item click events if the items themselves
      * do not have individual item click listeners.
      */
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 8a9cb22..ea36e37 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.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
@@ -246,6 +247,13 @@
     }
 
     @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        init(getContext());
+        requestApplyInsets();
+    }
+
+    @Override
     public void onWindowSystemUiVisibilityChanged(int visible) {
         super.onWindowSystemUiVisibilityChanged(visible);
         pullChildren();
@@ -329,7 +337,7 @@
         // insets in all cases, we need to know the measured size of the various action
         // bar elements.  onApplyWindowInsets() happens before the measure pass, so we can't
         // do that here.  Instead we will take this up in onMeasure().
-        return WindowInsets.EMPTY;
+        return WindowInsets.CONSUMED;
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index b298d85..bed0b88 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -424,7 +424,7 @@
 
     @Override
     public void setCollapsible(boolean collapsible) {
-        // Ignore
+        mToolbar.setCollapsible(collapsible);
     }
 
     @Override
@@ -569,7 +569,7 @@
 
     @Override
     public void setNavigationIcon(int resId) {
-        setNavigationIcon(mToolbar.getContext().getDrawable(resId));
+        setNavigationIcon(resId != 0 ? mToolbar.getContext().getDrawable(resId) : null);
     }
 
     @Override
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 8e56eec..432a615 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -828,13 +828,12 @@
                 : layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs),
                     pos(pos) { }
 
-        void operator()(SkTypeface* t, size_t start, size_t end) {
+        void operator()(size_t start, size_t end) {
             for (size_t i = start; i < end; i++) {
                 glyphs[i] = layout.getGlyphId(i);
                 pos[i].fX = x + layout.getX(i);
                 pos[i].fY = y + layout.getY(i);
             }
-            paint->setTypeface(t);
             canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint);
         }
     private:
@@ -857,7 +856,7 @@
         paint->setTextAlign(SkPaint::kLeft_Align);
         paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
         DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos);
-        MinikinUtils::forFontRun(layout, f);
+        MinikinUtils::forFontRun(layout, paint, f);
         doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint);
         paint->setTextAlign(align);
         delete[] glyphs;
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
index 2b96f1b..25eb941 100644
--- a/core/jni/android/graphics/MinikinSkia.cpp
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -43,13 +43,14 @@
     return !!glyph;
 }
 
-static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
-    skPaint->setTypeface(typeface);
+static void MinikinFontSkia_SetSkiaPaint(const MinikinFont* font, SkPaint* skPaint, const MinikinPaint& paint) {
     skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
     skPaint->setTextSize(paint.size);
     skPaint->setTextScaleX(paint.scaleX);
     skPaint->setTextSkewX(paint.skewX);
     MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags);
+    // Apply font fakery on top of user-supplied flags.
+    MinikinFontSkia::populateSkPaint(skPaint, font, paint.fakery);
 }
 
 float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
@@ -57,7 +58,7 @@
     SkPaint skPaint;
     uint16_t glyph16 = glyph_id;
     SkScalar skWidth;
-    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+    MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
     skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL);
 #ifdef VERBOSE
     ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id, skWidth);
@@ -70,7 +71,7 @@
     SkPaint skPaint;
     uint16_t glyph16 = glyph_id;
     SkRect skBounds;
-    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+    MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
     skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds);
     bounds->mLeft = skBounds.fLeft;
     bounds->mTop = skBounds.fTop;
@@ -90,7 +91,7 @@
     }
 }
 
-SkTypeface *MinikinFontSkia::GetSkTypeface() {
+SkTypeface *MinikinFontSkia::GetSkTypeface() const {
     return mTypeface;
 }
 
@@ -115,4 +116,12 @@
     paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16));
 }
 
+void MinikinFontSkia::populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery) {
+    paint->setTypeface(reinterpret_cast<const MinikinFontSkia*>(font)->GetSkTypeface());
+    paint->setFakeBoldText(paint->isFakeBoldText() || fakery.isFakeBold());
+    if (fakery.isFakeItalic()) {
+        paint->setTextSkewX(paint->getTextSkewX() - 0.25f);
+    }
+}
+
 }
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
index 0452c57..ac4d2a0 100644
--- a/core/jni/android/graphics/MinikinSkia.h
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -36,10 +36,13 @@
 
     int32_t GetUniqueId() const;
 
-    SkTypeface *GetSkTypeface();
+    SkTypeface* GetSkTypeface() const;
 
     static uint32_t packPaintFlags(const SkPaint* paint);
     static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
+
+    // set typeface and fake bold/italic parameters
+    static void populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery);
 private:
     SkTypeface *mTypeface;
 };
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index ea7eb5d..a96c6b1 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -36,23 +36,30 @@
 
     static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
 
-    // f is a functor of type void f(SkTypeface *, size_t start, size_t end);
+    // f is a functor of type void f(size_t start, size_t end);
     template <typename F>
-    static void forFontRun(const Layout& layout, F& f) {
-        SkTypeface* lastFace = NULL;
+    static void forFontRun(const Layout& layout, SkPaint* paint, F& f) {
+        float saveSkewX = paint->getTextSkewX();
+        bool savefakeBold = paint->isFakeBoldText();
+        MinikinFont* curFont = NULL;
         size_t start = 0;
         size_t nGlyphs = layout.nGlyphs();
         for (size_t i = 0; i < nGlyphs; i++) {
-            MinikinFontSkia* mfs = static_cast<MinikinFontSkia*>(layout.getFont(i));
-            SkTypeface* skFace = mfs->GetSkTypeface();
-            if (i > 0 && skFace != lastFace) {
-                f(lastFace, start, i);
+            MinikinFont* nextFont = layout.getFont(i);
+            if (i > 0 && nextFont != curFont) {
+                MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+                f(start, i);
+                paint->setTextSkewX(saveSkewX);
+                paint->setFakeBoldText(savefakeBold);
                 start = i;
             }
-            lastFace = skFace;
+            curFont = nextFont;
         }
         if (nGlyphs > start) {
-            f(lastFace, start, nGlyphs);
+            MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+            f(start, nGlyphs);
+            paint->setTextSkewX(saveSkewX);
+            paint->setFakeBoldText(savefakeBold);
         }
     }
 };
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 3dc874e..8b11d31 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -429,27 +429,29 @@
         GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
     }
 
-    static jfloat ascent(JNIEnv* env, jobject paint) {
-        NPE_CHECK_RETURN_ZERO(env, paint);
-        SkPaint::FontMetrics    metrics;
-        (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
-        return SkScalarToFloat(metrics.fAscent);
-    }
-
-    static jfloat descent(JNIEnv* env, jobject paint) {
-        NPE_CHECK_RETURN_ZERO(env, paint);
-        SkPaint::FontMetrics    metrics;
-        (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
-        return SkScalarToFloat(metrics.fDescent);
-    }
-
-    static SkScalar getMetricsInternal(SkPaint *paint, SkPaint::FontMetrics *metrics) {
+    static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, SkPaint::FontMetrics *metrics) {
         const int kElegantTop = 2500;
         const int kElegantBottom = -1000;
-        const int kElegantAscent = 1946;
-        const int kElegantDescent = -512;
+        const int kElegantAscent = 1900;
+        const int kElegantDescent = -500;
         const int kElegantLeading = 0;
+        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+#ifdef USE_MINIKIN
+        TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
+        typeface = TypefaceImpl_resolveDefault(typeface);
+        FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle);
+        float saveSkewX = paint->getTextSkewX();
+        bool savefakeBold = paint->isFakeBoldText();
+        MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery);
+#endif
         SkScalar spacing = paint->getFontMetrics(metrics);
+#ifdef USE_MINIKIN
+        // The populateSkPaint call may have changed fake bold / text skew
+        // because we want to measure with those effects applied, so now
+        // restore the original settings.
+        paint->setTextSkewX(saveSkewX);
+        paint->setFakeBoldText(savefakeBold);
+#endif
         SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
         if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
             SkScalar size = paint->getTextSize();
@@ -463,10 +465,24 @@
         return spacing;
     }
 
+    static jfloat ascent(JNIEnv* env, jobject paint) {
+        NPE_CHECK_RETURN_ZERO(env, paint);
+        SkPaint::FontMetrics metrics;
+        getMetricsInternal(env, paint, &metrics);
+        return SkScalarToFloat(metrics.fAscent);
+    }
+
+    static jfloat descent(JNIEnv* env, jobject paint) {
+        NPE_CHECK_RETURN_ZERO(env, paint);
+        SkPaint::FontMetrics metrics;
+        getMetricsInternal(env, paint, &metrics);
+        return SkScalarToFloat(metrics.fDescent);
+    }
+
     static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics metrics;
-        SkScalar spacing = getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
+        SkScalar spacing = getMetricsInternal(env, paint, &metrics);
 
         if (metricsObj) {
             SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
@@ -483,7 +499,7 @@
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics metrics;
 
-        getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
+        getMetricsInternal(env, paint, &metrics);
         int ascent = SkScalarRoundToInt(metrics.fAscent);
         int descent = SkScalarRoundToInt(metrics.fDescent);
         int leading = SkScalarRoundToInt(metrics.fLeading);
@@ -830,13 +846,12 @@
                 : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) {
         }
 
-        void operator()(SkTypeface* t, size_t start, size_t end) {
+        void operator()(size_t start, size_t end) {
             for (size_t i = start; i < end; i++) {
                 glyphs[i] = layout.getGlyphId(i);
                 pos[i].fX = x + layout.getX(i);
                 pos[i].fY = y + layout.getY(i);
             }
-            paint->setTypeface(t);
             if (start == 0) {
                 paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path);
             } else {
@@ -871,7 +886,7 @@
         paint->setTextAlign(SkPaint::kLeft_Align);
         paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
         GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
-        MinikinUtils::forFontRun(layout, f);
+        MinikinUtils::forFontRun(layout, paint, f);
         paint->setTextAlign(align);
         delete[] glyphs;
         delete[] pos;
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
index 27df7cf..1800d0c 100644
--- a/core/jni/android/graphics/TypefaceImpl.cpp
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -173,7 +173,7 @@
     } else {
         const FontStyle defaultStyle;
         FontFamily* firstFamily = reinterpret_cast<FontFamily*>(families[0]);
-        MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle);
+        MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font;
         SkTypeface* skTypeface = reinterpret_cast<MinikinFontSkia*>(mf)->GetSkTypeface();
         // TODO: probably better to query more precise style from family, will be important
         // when we open up API to access 100..900 weights
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a46ccd6..d032cb6 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -656,13 +656,12 @@
                 uirenderer::Rect& bounds)
             : layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
             pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
-    void operator()(SkTypeface* t, size_t start, size_t end) {
+    void operator()(size_t start, size_t end) {
         for (size_t i = start; i < end; i++) {
             glyphs[i] = layout.getGlyphId(i);
             pos[2 * i] = layout.getX(i);
             pos[2 * i + 1] = layout.getY(i);
         }
-        paint->setTypeface(t);
         size_t glyphsCount = end - start;
         int bytesCount = glyphsCount * sizeof(jchar);
         renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
@@ -692,7 +691,7 @@
     float totalAdvance = layout->getAdvance();
 
     RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
-    MinikinUtils::forFontRun(*layout, f);
+    MinikinUtils::forFontRun(*layout, paint, f);
     delete[] glyphs;
     delete[] pos;
 }
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 230658f..381a5ee 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -324,6 +324,7 @@
 
             // Exception: If we find the gdbserver binary, return it.
             if (!strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
+                mLastSlash = lastSlash;
                 break;
             }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3696806..c5fd83d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1758,11 +1758,11 @@
 
     <!-- Allows the system to bind to an application's task services
          @hide -->
-    <permission android:name="android.permission.BIND_TASK_SERVICE"
+    <permission android:name="android.permission.BIND_JOB_SERVICE"
         android:protectionLevel="signature"
-        android:label="@string/permlab_bindTaskService"
-        android:description="@string/permdesc_bindTaskService" />
-    <uses-permission android:name="android.permission.BIND_TASK_SERVICE"/>
+        android:label="@string/permlab_bindJobService"
+        android:description="@string/permdesc_bindJobService" />
+    <uses-permission android:name="android.permission.BIND_JOB_SERVICE"/>
 
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
@@ -2688,7 +2688,8 @@
                 android:theme="@style/Theme.Holo.Dialog.Alert"
                 android:finishOnCloseSystemDialogs="true"
                 android:excludeFromRecents="true"
-                android:multiprocess="true">
+                android:multiprocess="true"
+                android:documentLaunchMode="never">
             <intent-filter>
                 <action android:name="android.intent.action.CHOOSER" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -2877,8 +2878,8 @@
         </service>
 
         <service android:name="com.android.server.MountServiceIdler"
-                 android:exported="false"
-                 android:permission="android.permission.BIND_TASK_SERVICE" >
+                 android:exported="true"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
     </application>
diff --git a/core/res/res/anim-land/task_close_enter.xml b/core/res/res/anim-land/task_close_enter.xml
deleted file mode 100644
index facc42b..0000000
--- a/core/res/res/anim-land/task_close_enter.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
-
-    <alpha android:fromAlpha="0" android:toAlpha="1.0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="300"
-            android:duration="400"/>
-
-    <translate android:fromXDelta="-120%" android:toXDelta="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="300"
-            android:duration="400" />
-
-    <scale android:fromXScale=".5" android:toXScale="1.0"
-            android:fromYScale=".5" android:toYScale="1.0"
-            android:pivotY="50%p" android:pivotX="0%p"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="300"
-            android:duration="400" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/anim-land/task_close_exit.xml b/core/res/res/anim-land/task_close_exit.xml
deleted file mode 100644
index e104c33..0000000
--- a/core/res/res/anim-land/task_close_exit.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
-
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="300"/>
-
-    <translate android:fromXDelta="0" android:toXDelta="120%"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_cubic"
-            android:duration="300"/>
-
-    <scale android:fromXScale="1.0" android:toXScale="0.5"
-            android:fromYScale="1.0" android:toYScale="0.5"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:pivotY="50%p" android:pivotX="100%p"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="300" />
-
-    <!-- This is needed to keep the animation running while task_open_enter completes -->
-    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-            android:duration="700" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/anim-land/task_open_enter.xml b/core/res/res/anim-land/task_open_enter.xml
deleted file mode 100644
index dc7c7a9..0000000
--- a/core/res/res/anim-land/task_open_enter.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
-
-    <alpha android:fromAlpha="0" android:toAlpha="1.0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="300"
-            android:duration="400"/>
-
-    <translate android:fromXDelta="120%" android:toXDelta="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="300"
-            android:duration="400" />
-
-    <scale android:fromXScale=".5" android:toXScale="1.0"
-            android:fromYScale=".5" android:toYScale="1.0"
-            android:pivotY="50%p" android:pivotX="100%p"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="300"
-            android:duration="400" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/anim-land/task_open_exit.xml b/core/res/res/anim-land/task_open_exit.xml
deleted file mode 100644
index 701afa6..0000000
--- a/core/res/res/anim-land/task_open_exit.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
-
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="300"/>
-
-    <translate android:fromXDelta="0" android:toXDelta="-120%"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_cubic"
-            android:duration="300"/>
-
-    <scale android:fromXScale="1.0" android:toXScale="0.5"
-            android:fromYScale="1.0" android:toYScale="0.5"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:pivotY="50%p" android:pivotX="0%p"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="300" />
-
-    <!-- This is needed to keep the animation running while task_open_enter completes -->
-    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-            android:duration="700" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/anim-sw720dp/task_close_enter.xml b/core/res/res/anim-sw720dp/task_close_enter.xml
deleted file mode 100644
index e25978b..0000000
--- a/core/res/res/anim-sw720dp/task_close_enter.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
-
-    <alpha android:fromAlpha="0" android:toAlpha="1.0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="500"
-            android:duration="400"/>
-
-    <translate android:fromYDelta="-50%" android:toYDelta="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="500"
-            android:duration="400" />
-
-    <scale android:fromXScale=".8" android:toXScale="1.0"
-            android:fromYScale=".8" android:toYScale="1.0"
-            android:pivotX="50%p" android:pivotY="0%p"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="500"
-            android:duration="400" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/anim-sw720dp/task_close_exit.xml b/core/res/res/anim-sw720dp/task_close_exit.xml
deleted file mode 100644
index 2d7e2a6..0000000
--- a/core/res/res/anim-sw720dp/task_close_exit.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
-
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="350"/>
-
-    <translate android:fromYDelta="0" android:toYDelta="50%"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_cubic"
-            android:duration="350"/>
-
-    <scale android:fromXScale="1.0" android:toXScale="0.8"
-            android:fromYScale="1.0" android:toYScale="0.8"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:pivotX="50%p" android:pivotY="100%p"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="350" />
-
-    <!-- This is needed to keep the animation running while task_close_enter completes -->
-    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-            android:duration="900" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/anim-sw720dp/task_open_enter.xml b/core/res/res/anim-sw720dp/task_open_enter.xml
deleted file mode 100644
index d583b6e..0000000
--- a/core/res/res/anim-sw720dp/task_open_enter.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
-
-    <alpha android:fromAlpha="0" android:toAlpha="1.0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="500"
-            android:duration="400"/>
-
-    <translate android:fromYDelta="50%" android:toYDelta="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="500"
-            android:duration="400" />
-
-    <scale android:fromXScale=".8" android:toXScale="1.0"
-            android:fromYScale=".8" android:toYScale="1.0"
-            android:pivotX="50%p" android:pivotY="100%p"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_quad"
-            android:startOffset="500"
-            android:duration="400" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/anim-sw720dp/task_open_exit.xml b/core/res/res/anim-sw720dp/task_open_exit.xml
deleted file mode 100644
index dd25a0c..0000000
--- a/core/res/res/anim-sw720dp/task_open_exit.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
-
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="350"/>
-
-    <translate android:fromYDelta="0" android:toYDelta="-50%"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_cubic"
-            android:duration="350"/>
-
-    <scale android:fromXScale="1.0" android:toXScale="0.8"
-            android:fromYScale="1.0" android:toYScale="0.8"
-            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
-            android:pivotX="50%p" android:pivotY="0%p"
-            android:interpolator="@interpolator/accelerate_quad"
-            android:duration="350" />
-
-    <!-- This is needed to keep the animation running while task_open_enter completes -->
-    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-            android:duration="900" />
-</set>
\ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..0c3c3b4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..8322ae3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..e6c0047
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..bb9debb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_borderless_material.xml b/core/res/res/drawable/btn_borderless_material.xml
index 1967b38..a459089 100644
--- a/core/res/res/drawable/btn_borderless_material.xml
+++ b/core/res/res/drawable/btn_borderless_material.xml
@@ -15,7 +15,7 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="?attr/colorControlHighlight">
+    android:color="?attr/colorControlHighlight">
     <item android:id="@id/mask"
         android:drawable="@drawable/btn_mtrl_alpha" />
 </ripple>
diff --git a/core/res/res/drawable/btn_default_material.xml b/core/res/res/drawable/btn_default_material.xml
index acec900..9cee3ab 100644
--- a/core/res/res/drawable/btn_default_material.xml
+++ b/core/res/res/drawable/btn_default_material.xml
@@ -15,7 +15,7 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="?attr/colorControlHighlight">
+    android:color="?attr/colorControlHighlight">
     <item>
         <nine-patch android:src="@drawable/btn_mtrl_alpha"
             android:tint="?attr/colorButtonNormal" />
diff --git a/core/res/res/drawable/btn_toggle_material.xml b/core/res/res/drawable/btn_toggle_material.xml
index 4532c77..73fe4d3 100644
--- a/core/res/res/drawable/btn_toggle_material.xml
+++ b/core/res/res/drawable/btn_toggle_material.xml
@@ -21,7 +21,7 @@
     android:insetRight="4dp">
     <layer-list android:paddingMode="stack">
         <item>
-            <ripple android:tint="?attr/colorControlHighlight">
+            <ripple android:color="?attr/colorControlHighlight">
                 <item>
                     <nine-patch android:src="@drawable/btn_toggle_mtrl_alpha"
                         android:tint="?attr/colorButtonNormal" />
diff --git a/core/res/res/drawable/dialog_background_shadow_material.xml b/core/res/res/drawable/dialog_background_shadow_material.xml
new file mode 100644
index 0000000..0554920
--- /dev/null
+++ b/core/res/res/drawable/dialog_background_shadow_material.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.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/dialog_background_mtrl_mult"
+    android:tint="?attr/colorBackground"
+    android:tintMode="multiply" />
diff --git a/core/res/res/drawable/edit_text_material.xml b/core/res/res/drawable/edit_text_material.xml
index 26fd889..86cec8f 100644
--- a/core/res/res/drawable/edit_text_material.xml
+++ b/core/res/res/drawable/edit_text_material.xml
@@ -15,8 +15,7 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="?attr/colorControlActivated"
-    android:tintMode="src_over">
+    android:color="?attr/colorControlActivated">
     <item>
         <selector>
             <item android:state_enabled="false">
diff --git a/core/res/res/drawable/item_background_borderless_material.xml b/core/res/res/drawable/item_background_borderless_material.xml
index c2a1c127..b730618 100644
--- a/core/res/res/drawable/item_background_borderless_material.xml
+++ b/core/res/res/drawable/item_background_borderless_material.xml
@@ -15,5 +15,4 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="?attr/colorControlHighlight"
-    android:pinned="true" />
+    android:color="?attr/colorControlHighlight" />
diff --git a/core/res/res/drawable/item_background_material.xml b/core/res/res/drawable/item_background_material.xml
index 039ca51..45ff181 100644
--- a/core/res/res/drawable/item_background_material.xml
+++ b/core/res/res/drawable/item_background_material.xml
@@ -15,8 +15,8 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="?attr/colorControlHighlight">
+    android:color="?attr/colorControlHighlight">
     <item android:id="@id/mask">
         <color android:color="@color/white" />
     </item>
-</ripple>
\ No newline at end of file
+</ripple>
diff --git a/core/res/res/drawable/notification_bg_dim.xml b/core/res/res/drawable/notification_bg_dim.xml
index ae03d82..5c245f8 100644
--- a/core/res/res/drawable/notification_bg_dim.xml
+++ b/core/res/res/drawable/notification_bg_dim.xml
@@ -15,9 +15,7 @@
   ~ limitations under the License
   -->
 
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="#ff444444"
-    >
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="#ff444444">
     <item android:drawable="@drawable/notification_bg_normal" />
 </ripple>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_material_bg_dim.xml b/core/res/res/drawable/notification_material_bg_dim.xml
index a908be7..9b691e6 100644
--- a/core/res/res/drawable/notification_material_bg_dim.xml
+++ b/core/res/res/drawable/notification_material_bg_dim.xml
@@ -15,15 +15,18 @@
   ~ limitations under the License
   -->
 
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tint="#ffffffff"
-    android:tintMode="src_over"
-    >
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/white">
     <item>
         <shape>
             <solid android:color="#d4ffffff" />
             <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
         </shape>
     </item>
-</ripple>
\ No newline at end of file
+    <item android:id="@id/mask">
+        <shape>
+            <solid android:color="@color/white" />
+            <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
+        </shape>
+    </item>
+</ripple>
diff --git a/core/res/res/layout/dialog_custom_title_material.xml b/core/res/res/layout/dialog_custom_title_material.xml
index 1bb93eb..550b72e 100644
--- a/core/res/res/layout/dialog_custom_title_material.xml
+++ b/core/res/res/layout/dialog_custom_title_material.xml
@@ -23,6 +23,7 @@
     android:fitsSystemWindows="true">
     <FrameLayout android:id="@android:id/title_container"
         android:layout_width="match_parent"
+        android:layout_height="?android:attr/windowTitleSize"
         android:layout_weight="0"
         android:gravity="center_vertical|start"
         style="?android:attr/windowTitleBackgroundStyle" />
diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml
index b92c1e7..918c8f1 100644
--- a/core/res/res/layout/dialog_title_material.xml
+++ b/core/res/res/layout/dialog_title_material.xml
@@ -22,7 +22,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:fitsSystemWindows="true">
-    <TextView android:id="@+id/alertTitle"
+    <TextView android:id="@+id/title"
         style="?android:attr/windowTitleStyle"
         android:singleLine="true"
         android:ellipsize="end"
diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
index bdf27c8..0564a8f 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -145,7 +145,7 @@
                 android:layout_marginStart="8dp"
                 android:layout_marginEnd="8dp"
                 android:visibility="gone"
-                style="@style/Widget.Material.Light.ProgressBar.Horizontal"
+                style="@style/Widget.StatusBar.Material.ProgressBar"
                 />
         </LinearLayout>
         <ImageView
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index c89b9f9..f8e1986 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -38,7 +38,6 @@
             android:minHeight="@dimen/notification_large_icon_height"
             android:paddingTop="2dp"
             android:orientation="vertical"
-            android:background="@color/notification_media_info_bg"
             >
             <LinearLayout
                 android:id="@+id/line1"
@@ -147,7 +146,7 @@
                 android:layout_height="6dp"
                 android:layout_gravity="top"
                 android:visibility="gone"
-                style="@style/Widget.StatusBar.Material.ProgressBar"
+                style="@style/Widget.StatusBar.Material.ProgressBar.Media"
                 />
         </FrameLayout>
     </LinearLayout>
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 6f8c3a9..1de5add 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -99,7 +99,7 @@
                 android:layout_marginEnd="8dp"
                 android:visibility="gone"
                 android:layout_weight="0"
-                style="@style/Widget.Material.Light.ProgressBar.Horizontal"
+                style="@style/Widget.StatusBar.Material.ProgressBar"
                 />
             <TextView android:id="@+id/big_text"
                 android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent"
diff --git a/core/res/res/layout/preference_material.xml b/core/res/res/layout/preference_material.xml
index a4fe73d..a9599139 100644
--- a/core/res/res/layout/preference_material.xml
+++ b/core/res/res/layout/preference_material.xml
@@ -31,7 +31,7 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:minWidth="58dip"
-        android:gravity="left|center_vertical"
+        android:gravity="start|center_vertical"
         android:orientation="horizontal">
         <ImageView
             android:id="@+android:id/icon"
diff --git a/core/res/res/layout/preference_widget_checkbox.xml b/core/res/res/layout/preference_widget_checkbox.xml
index bfd7f0a..f794346 100644
--- a/core/res/res/layout/preference_widget_checkbox.xml
+++ b/core/res/res/layout/preference_widget_checkbox.xml
@@ -21,4 +21,5 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:focusable="false"
-    android:clickable="false" />
+    android:clickable="false"
+    android:background="@null" />
diff --git a/core/res/res/layout/preference_widget_switch.xml b/core/res/res/layout/preference_widget_switch.xml
index 534c7ec..04a310b 100644
--- a/core/res/res/layout/preference_widget_switch.xml
+++ b/core/res/res/layout/preference_widget_switch.xml
@@ -21,4 +21,5 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:padding="16dip"
-    android:focusable="false" />
+    android:focusable="false"
+    android:background="@null" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 07449ab..2321915 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-stelsel"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Persoonlik"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Persoonlike programme"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Werk"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Dienste wat jou geld kos"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Doen dinge wat jou geld kan kos."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Jou boodskappe"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"laat loop die program se geskeduleerde agtergrondwerk"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Hierdie toestemming laat die Android-stelsel toe om die program in die agtergrond te laat loop wanneer dit versoek word."</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>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 67406cb..14d0af2 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"የግል"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"ስራ"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"የግል መተግበሪያዎች"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android ስራ"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"ገንዘብ የሚያስወጥዎ አገልግሎቶች"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ገንዘብ የሚያስወጡህን ነገሮች አድርግ።"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"መልዕክቶችዎ"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"መርሐግብር የተያዘለት የመተግበሪያ የጀርባ ስራ አሂድ"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"ይህ ፍቃድ የ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>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index f8e5272..319d210 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"شخصي"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"عمل"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"التطبيقات الشخصية"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"‏عمل Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"الخدمات التي تكلفك المال"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"يمكنك تنفيذ إجراءات يمكن أن تكلفك مالاً."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"رسائلك"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"تشغيل عمل الخلفية المجدول للتطبيق"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"‏يتيح هذا الإذن لنظام Android تشغيل التطبيق في الخلفية عند طلبه."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"قراءة/كتابة إلى الموارد المملوكة بواسطة التشخيص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏للسماح للتطبيق بالقراءة والكتابة إلى أي مورد مملوك بواسطة مجموعة التشخيصات؛ على سبيل المثال، الملفات في /dev. من المحتمل أن يؤثر ذلك في استقرار النظام وأمانه. يجب ألا يستخدم ذلك سوى للتشخيصات الخاصة بالنظام من قِبل المصنِّع أو المشغِّل."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"تمكين مكونات التطبيق أو تعطيلها"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 1a13170..21545aa 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"Личен"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Служебен"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Лични приложения"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Услуги, които ви струват пари"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Извършват неща, които могат да ви струват пари."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Вашите съобщения"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"изпълняване на планираната за извършване на заден план работа на приложението"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Това разрешение позволява на системата 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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4368908..ef5b1801 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Feina"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplicacions personals"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Lloc a Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Serveis de pagament"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Dur a terme activitats de pagament."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Missatges"</string>
@@ -265,8 +265,8 @@
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permet que l\'aplicació desactivi la barra d\'estat o afegeixi i elimini icones del sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra d\'estat"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Permet que l\'aplicació sigui la barra d\'estat."</string>
-    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"ampliar/reduir la barra d\'estat"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Permet que l\'aplicació ampliï o redueixi la barra d\'estat."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"desplega/contrau la barra d\'estat"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Permet que l\'aplicació desplegui o replegui la barra d\'estat."</string>
     <string name="permlab_install_shortcut" msgid="4279070216371564234">"instal·la dreceres"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Permet que una aplicació afegeixi dreceres a la pantalla d\'inici sense la intervenció de l\'usuari."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstal·la dreceres"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"executa les tasques programades de l\'aplicació en segon pla"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Mitjançant aquest permís, el sistema Android pot executar l\'aplicació en segon pla quan se li ho sol·liciti."</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>
@@ -941,7 +941,7 @@
     <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"S\'ha iniciat la reorganització del widget."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ha finalitzat la reorganització del widget."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"S\'ha suprimit el widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
-    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Amplia l\'àrea de desbloqueig."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Desplega l\'àrea de desbloqueig."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant el dit"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueig mitjançant patró"</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueig facial"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index cb8a70a..0526038 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Osobní"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Práce"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Osobní aplikace"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android pro práci"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Zpoplatněné služby"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Provádět činnosti, které vás mohou stát peníze."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Vaše zprávy"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"spustit naplánovanou práci aplikace na pozadí"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Toto oprávnění umožňuje systému Android spustit aplikaci na pozadí, když je to požadová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>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index a3f71d7..e3b89dd 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personlig"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Arbejde"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Personlige apps"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tjenester, der koster dig penge"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Gør ting, der kan koste dig penge."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Dine beskeder"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"kør applikationens planlagte baggrundsarbejde"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Med denne tilladelse kan Android-systemet køre applikationen i baggrunden, når det er nødvendigt."</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>
@@ -521,7 +521,7 @@
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Registrering af kommandoord"</string>
     <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Tillader, at appen optager lyd til registrering af kommandoord. Optagelsen kan ske i baggrunden, men forhindrer ikke andre lydoptagelser (f.eks. videokamera)."</string>
     <string name="permlab_modifyAudioRouting" msgid="7738060354490807723">"Lydhåndtering"</string>
-    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"Tillader, at appen direkte kontrollerer lydhåndteringen og tilsidesætter beslutninger, som foretages af lydpolitikker."</string>
+    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"Tillader, at appen direkte kontrollerer lydhåndteringen og tilsidesætter beslutninger, baseret på af lydpolitikker."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"opfang et videooutput"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Tillader, at appen opfanger og omdirigerer et videooutput."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"opfang et sikkert videooutput"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 293adf3..35116c3 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-System"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Privat"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Geschäftlich"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Private Apps"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android – Arbeit"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Kostenpflichtige Dienste"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Kostenpflichtige Aktionen"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Ihre Nachrichten"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"Geplante Aufgaben der App im Hintergrund ausführen"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Diese Berechtigung ermöglicht es dem Android-System, die App bei Bedarf im Hintergrund auszuführen."</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>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 553c27a..0c50bb5 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"Προσωπικό"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Εργασία"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Προσωπικές εφαρμογές"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Υπηρεσίες επί πληρωμή"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Πραγματοποίηση ενεργειών για τις οποίες ενδέχεται να χρεωθείτε."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Τα μηνύματά σας"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"εκτέλεση των προγραμματισμένων εργασιών της εφαρμογής στο παρασκήνιο"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Αυτή η άδεια επιτρέπει στο σύστημα Android να εκτελεί την εφαρμογή στο παρασκήνιο όταν ζητηθεί."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ανάγνωση/εγγραφή σε πόρους που ανήκουν στο διαγνωστικό"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Επιτρέπει στην εφαρμογή την ανάγνωση και την εγγραφή σε οποιονδήποτε πόρο που ανήκει στην ομάδα διαγνωστικού (π.χ. αρχεία στον κατάλογο /dev). Αυτό ενδέχεται να επηρεάσει την σταθερότητα και την ασφάλεια του συστήματος. Θα πρέπει να χρησιμοποιείται ΜΟΝΟ για διαγνωστικά υλικού από τον κατασκευαστή ή τον χειριστή."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 69cb424..32141c3 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Personal apps"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services that cost you money"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Do things that can cost you money."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Your messages"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"run the application\'s scheduled background work"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"This permission allows the Android system to run the application in the background when requested."</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>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 69cb424..32141c3 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Personal apps"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services that cost you money"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Do things that can cost you money."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Your messages"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"run the application\'s scheduled background work"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"This permission allows the Android system to run the application in the background when requested."</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>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 9ffdfe6..3eb0666 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Trabajo"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplicaciones personales"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Trabajo Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servicios que te cuestan dinero"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Permite que las aplicaciones realicen actividades con cargo."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Tus mensajes"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"Ejecutar el trabajo en segundo plano programado de la aplicación"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Con este permiso, el sistema Android puede ejecutar la aplicación en segundo plano cuando sea necesario."</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>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index cf1f4fd..126d20d 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt; 999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Trabajo"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplicaciones personales"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Trabajo Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servicios por los que tienes que pagar"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Hacer acciones por las que puede que tengas que pagar"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Tus mensajes"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"ejecutar el trabajo en segundo plano programado de la aplicación"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Esto permite que el sistema Android ejecute la aplicación en segundo plano cuando se solicite."</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>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 5e0d319..71a19f0 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"Isiklik"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Töö"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Isiklikud rakendused"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android tööl"</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>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"rakenduse ajastatud taustatoimingu käitamine"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"See luba võimaldab Android-süsteemil rakendust soovi korral taustal käitada."</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>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 1cb008c..8cf01d9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"شخصی"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"محل کار"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"برنامه‌های شخصی"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"سرویس‌های غیر رایگان"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"انجام کارهایی که برای شما هزینه دارد."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"پیام‌های شما"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"اجرای کار پس‌زمینه زمان‌بندی شده برای برنامه"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"‏این مجوز، به سیستم Android امکان می‌دهد در صورت تقاضا، برنامه را در پس‌زمینه اجرا کند."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"خواندن/نوشتن منابع متعلق به تشخیص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"‏به برنامه اجازه می‌دهد هر منبعی را که متعلق به گروه تشخیص است بخواند و در آن بنویسد؛ به‌عنوان مثال، فایل‌های /dev. این امر به‌صورت بالقوه می‌تواند بر پایدار بودن و امنیت سیستم تأثیر بگذارد. این تنها باید برای تشخیص‎‌های مختص سخت‌افزار توسط تولیدکننده یا اپراتور استفاده شود."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"فعال یا غیر فعال کردن اجزای برنامه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f792aff..2852844 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-järjestelmä"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Henkilökohtainen"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Työ"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Omat sovellukset"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Maksulliset palvelut"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Suorita mahdollisesti maksullisia toimintoja."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Omat viestit"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"suorittaa sovelluksen ajoitetut taustatyöt"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Tämä antaa Android-järjestelmän suorittaa sovelluksen pyydettäessä taustalla."</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>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index c43fe1e..f3e6322 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personnel"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Travail"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Applications personnelles"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android pour les activités professionnelles"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services payants"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Effectuer des opérations payantes"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Vos messages"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"exécuter le travail en arrière-plan planifié de l\'application"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Cette autorisation permet au système Android d\'exécuter l\'application en arrière-plan sur demande."</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>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d755f05..cfb37c2 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personnel"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Professionnel"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Applications personnelles"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services payants"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Effectuer des opérations payantes"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Vos messages"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"exécuter les tâches en arrière-plan planifiées de l\'application"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Cette autorisation permet au système Android d\'exécuter l\'application en arrière-plan sur demande."</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>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index ff4412ea..bf22360 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"व्यक्तिगत"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"कार्यालय"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"व्यक्तिगत ऐप्स"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android कार्य"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"वे सेवाएं जिन पर आप खर्चा करते हैं"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ऐसे कार्य करें जिससे आपका धन खर्च हो सकता है."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"आपके संदेश"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"एप्लिकेशन का शेड्यूल किया गया पृष्ठभूमि कार्य चलाएं"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"यह अनुमति 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>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 4794fac..c5da5d8 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Osobno"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Posao"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Osobne aplikacije"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android za posao"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Usluge koje se plaćaju"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Radite stvari koje će uzrokovati novčane troškove."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Vaše poruke"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"izvršavaj planirani rad aplikacije u pozadini"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"To dopuštenje omogućuje sustavu Android izvođenje aplikacije u pozadini na zahtjev."</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>
@@ -520,8 +520,8 @@
     <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Omogućuje aplikaciji primanje i preusmjeravanje audioizlaza."</string>
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Otkrivanje pokretača značajke"</string>
     <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Aplikaciji omogućuje snimanje zvuka radi otkrivanja pokretača značajke. Snimanje se može odvijati u pozadini, ali ne sprječava drugo snimanje zvuka (npr. kameru)."</string>
-    <string name="permlab_modifyAudioRouting" msgid="7738060354490807723">"Preusmjeravanje audija"</string>
-    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"Omogućuje aplikaciji izravno upravljanje preusmjeravanjem audija i premošćivanje odluka pravila o audiju."</string>
+    <string name="permlab_modifyAudioRouting" msgid="7738060354490807723">"Preusmjeravanje zvučnog zapisa"</string>
+    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"Omogućuje aplikaciji izravno upravljanje preusmjeravanjem zvučnog zapisa i zaobilaženje odluka pravila o zvučnim zapisima."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"primanje videoizlaza"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Omogućuje aplikaciji primanje i preusmjeravanje videoizlaza."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"primanje sigurnog videoizlaza"</string>
@@ -1356,8 +1356,8 @@
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Omogućuje aplikaciji upravljanje zaključavanjem tipkovnice."</string>
     <string name="permlab_trust_listener" msgid="1765718054003704476">"Prati promjene pouzdanog stanja."</string>
     <string name="permdesc_trust_listener" msgid="8233895334214716864">"Omogućuje aplikaciji praćenje promjena pouzdanog stanja."</string>
-    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Pružanje pouzdanog predstavnika."</string>
-    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Omogućuje aplikaciji pružanje pouzdanog predstavnika."</string>
+    <string name="permlab_provide_trust_agent" msgid="5465587586091358316">"Pružanje agenta za pouzdanost."</string>
+    <string name="permdesc_provide_trust_agent" msgid="3865702641053068148">"Omogućuje aplikaciji pružanje agenta za pouzdanost."</string>
     <string name="permlab_bind_trust_agent_service" msgid="8242093169457695334">"Povezivanje s uslugom pouzdanog predstavnika"</string>
     <string name="permdesc_bind_trust_agent_service" msgid="7041930026024507515">"Omogućuje aplikaciji povezivanje s uslugom pouzdanog predstavnika."</string>
     <string name="permlab_recovery" msgid="3157024487744125846">"Interakcija s ažuriranjem i sustavom za oporavak"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 136075b..414941f 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Személyes"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Munkahelyi"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Személyes alkalmazások"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Munkahelyi Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Fizetős szolgáltatások"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Olyan dolgok végrehajtása, amelyek pénzbe kerülnek."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Saját üzenetek"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"az alkalmazás ütemezett műveleteinek futtatása a háttérben"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Az engedély lehetővé teszi az Android számára, hogy kérés esetén a háttérben futtassa az alkalmazást."</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>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index d7adca7..60b55a1 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"Անձնական"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Աշխատանքային"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Անձնական ​​ծրագրեր"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Ծառայություններ, որոնց համար կգանձվեք"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Կատարել գործողություններ, որի դիմաց ձեր հաշվից գումար կծախսվի:"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Ձեր հաղորդագրությունները"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"աշխատեցնել ծրագրի ֆոնային ռեժիմում պլանավորված աշխատանքը"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Այս թույլտվության շնորհիվ Android համակարգն անհրաժեշտության դեպքում կարող է աշխատեցնել ծրագիրը ֆոնային ռեժիմում:"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"կարդալ կամ գրել ախտորոշիչին պատկանող ռեսուրսները"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Թույլ է տալիս հավելվածին կարդալ և գրել ախտորոշիչ խմբին պատկանող ցանկացած ռեսուրսում, ինչպես օրինակ ֆայլերը /dev-ում: Դա կարող է ազդել համակարգի կայունության և անվտանգության վրա: Սա պետք է օգտագործել միայն արտադրողի կամ օպերատորի կողմից սարքին հատուկ ախտորոշման համար:"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"միացնել կամ անջատել հավելվածի բաղադրիչները"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 8ace2df..2033596 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Pribadi"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Kantor"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplikasi pribadi"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Layanan berbayar"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Lakukan hal yang dapat dikenai biaya."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Pesan Anda"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"jalankan pekerjaan latar belakang yang terjadwal milik aplikasi"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Izin ini memungkinkan sistem Android menjalankan aplikasi di latar belakang saat diminta."</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>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 56e309b..3fd984b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personale"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Lavoro"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"App personali"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servizi che prevedono un costo"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Svolgono operazioni che possono comportare un costo."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"I tuoi messaggi"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"esegui operazioni pianificate in background dell\'applicazione"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Questa autorizzazione consente al sistema Android di eseguire l\'applicazione in background quando richiesto."</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>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6f06252..1f2b75c 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"אישי"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"עבודה"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"אפליקציות אישיות"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"‏Android לעבודה"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"שירותים שעולים כסף"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ביצוע פעולות שעשויות לעלות לך כסף."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"ההודעות שלך"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"הרץ את העבודה ברקע המתוזמנת של האפליקציה"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"‏ההרשאה הזו מאפשרת למערכת 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>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 8d22465..6aedff7 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"プライベート"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"職場"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"プライベートアプリ"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"料金の発生するサービス"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"料金発生の可能性がある操作を実行します。"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"送受信したメッセージ"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"アプリの予定されたバックグラウンド作業の実行"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"この権限により、リクエストされると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>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index be17c23..01824b2 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"პირადი"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"სამსახური"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"პერსონალური აპები"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android სამსახურისთვის"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"სერვისები, რომელშიც ფულის გადახდა გიწევთ"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ისეთი აქტივობების განხორციელება, რომლებშიც ფულის გადახდა მოგიწევთ."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"თქვენი შეტყობინებები"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"აპლიკაციის დაგეგმილი ფონური სამუშაოს გაშვება"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"ეს ნებართვა Android-ის სისტემას საშუალებას აძლევს მოთხოვნისას ფონში გაუშვას აპლიკაცია."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"სისტემის დიაგნოსტიკის რესურსებში წაკითხვა/ჩაწერის უფლება"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"აპს შეეძლება, წაიკითხოს ან ჩაწეროს ნებისმიერ რესურსში, რომელიც დიაგნოსტიკის ჯგუფს ეკუთვნის, მაგალითად, ფაილები /dev-ში. ამან შესაძლოა იმოქმედოს სისტემის სტაბილურობასა და უსაფრთხოებაზე. მისი გამოყენება მხოლოდ მწარმოებლის ან ოპერატორის მიერ ტექნიკის სპეციფიკური დიაგნოსტიკისთვის უნდა მოხდეს."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"აპის კომპონენტების ჩართვა ან გამორთვა"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index d5d1715f8..c2478e4 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -68,7 +68,7 @@
   </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"លេខ​សម្គាល់​អ្នក​ហៅ​​ចូល​"</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>
@@ -125,7 +125,7 @@
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> ៖ មិន​បាន​បញ្ជូន​បន្ត"</string>
     <string name="fcComplete" msgid="3118848230966886575">"កូដ​លក្ខណៈ​ពេញលេញ។"</string>
     <string name="fcError" msgid="3327560126588500777">"បញ្ហា​ការ​តភ្ជាប់​ ឬ​កូដ​លក្ខណៈ​​​មិន​ត្រឹមត្រូវ​។"</string>
-    <string name="httpErrorOk" msgid="1191919378083472204">"យល់​ព្រម​"</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"យល់​ព្រម"</string>
     <string name="httpError" msgid="7956392511146698522">"មាន​កំហុស​បណ្ដាញ។"</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"រក​មិន​ឃើញ URL ។"</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"គ្រោងការណ៍​ផ្ទៀងផ្ទាត់​តំបន់បណ្ដាញ​មិន​ត្រូវ​បាន​គាំទ្រ។"</string>
@@ -183,19 +183,19 @@
     <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="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បាន​បិទ​របៀបពេលជិះ​យន្តហោះ"</string>
     <string name="global_action_settings" msgid="1756531602592545966">"ការ​កំណត់"</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="user_owner_label" msgid="2804351898001038951">"ផ្ទាល់ខ្លួន"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"កន្លែង​ធ្វើ​ការ"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"កម្មវិធី​ផ្ទាល់​ខ្លួន"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</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="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>
@@ -384,7 +384,7 @@
     <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="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>
@@ -402,7 +402,7 @@
     <string name="permdesc_bindVoiceInteraction" msgid="2345721766501778101">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​ទៅ​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​​របស់​សេវាកម្ម​អន្តរកម្ម​សំឡេង។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"ភ្ជាប់​ទៅ​ការ​បង្ហាញ​ពី​ចម្ងាយ"</string>
     <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​​ទៅ​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​ការ​បង្ហាញ​ពី​ចម្ងាយ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
-    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចង​សេវា​កម្ម​ធាតុ​ក្រាហ្វិក​"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចង​សេវា​កម្ម​ធាតុ​ក្រាហ្វិក"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindRouteProvider" msgid="4869394607915096847">"ភ្ជាប់​ទៅ​សេវាកម្ម​ក្រុមហ៊ុន​ផ្ដល់​ច្រក"</string>
     <string name="permdesc_bindRouteProvider" msgid="4703804520859960329">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​ទៅ​ក្រុមហ៊ុន​ផ្ដល់​​ច្រក​ដែល​បាន​ចុះ​ឈ្មោះ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
@@ -410,7 +410,7 @@
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យ​ម្ចាស់​ផ្ញើ​គោលបំណង​​ទៅ​អ្នក​គ្រប់គ្រង​ឧបករណ៍។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindTvInput" msgid="5601264742478168987">"ភ្ជាប់​ទៅ​ការ​បញ្ចូល​ទូរទស្សន៍"</string>
     <string name="permdesc_bindTvInput" msgid="2371008331852001924">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​ទៅ​ចំណុចប្រទាក់​កម្រិត​ខ្ពស់​នៃ​ការ​បញ្ចូល​ទូរទស្សន៍។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
-    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​​​ឧបករណ៍​​"</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>
@@ -422,9 +422,9 @@
     <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="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>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"ដំណើរការ​ការងារ​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ​ដែល​បាន​កំណត់​ពេលវេលា​សម្រាប់​​កម្មវិធី"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​ប្រព័ន្ធ Android ​ដំណើរ​ការ​កម្មវិធី​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ​ពេល​បាន​ស្នើ។"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"អាន/សរសេរ​ធនធាន​គ្រប់គ្រង​ប្រអប់"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ឲ្យ​កម្មវិធី​អាន និង​សរសេរ​ប្រភព​ណាមួយ​ដែល​គ្រប់គ្រង​ដោយ​ក្រុម​អ្នក​វិនិច្ឆ័យ ឧទាហរណ៍ ឯកសារ​នៅ​ក្នុង /dev ។ វា​អាច​ប៉ះពាល់​យ៉ាង​ខ្លាំង​ដល់​ស្ថេរ​ភាព​ និង​សុវត្ថិភាព​ប្រព័ន្ធ។ វា​គួរ​ត្រូវ​បាន​ប្រើ​សម្រាប់​វិនិច្ឆ័យ​ផ្នែក​រឹង​ជាក់​លាក់​ដោយ​ក្រុមហ៊ុន​ផលិត ឬ​ប្រតិបត្តិ​ករ។"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"បិទ ឬ​បើក​សមាសធាតុ​កម្មវិធី"</string>
@@ -475,7 +475,7 @@
     <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="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>
@@ -609,7 +609,7 @@
     <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="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>
@@ -775,7 +775,7 @@
   <string-array name="organizationTypes">
     <item msgid="7546335612189115615">"កន្លែង​ធ្វើការ"</item>
     <item msgid="4378074129049520373">"ផ្សេងៗ"</item>
-    <item msgid="3455047468583965104">"តាម​តម្រូវ​ការ​"</item>
+    <item msgid="3455047468583965104">"តាម​តម្រូវ​ការ"</item>
   </string-array>
   <string-array name="imProtocols">
     <item msgid="8595261363518459565">"AIM"</item>
@@ -791,7 +791,7 @@
     <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="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារ​កន្លែង​ធ្វើការ"</string>
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"ទូរសារ​ផ្ទះ"</string>
     <string name="phoneTypePager" msgid="7582359955394921732">"ភេយ័រ"</string>
     <string name="phoneTypeOther" msgid="1544425847868765990">"ផ្សេងៗ"</string>
@@ -916,7 +916,7 @@
     <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_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>
@@ -961,7 +961,7 @@
     <string name="factorytest_failed" msgid="5410270329114212041">"បាន​បរាជ័យ​ក្នុង​ការ​សាកល្បង​រោងចក្រ"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវ​បាន​គាំទ្រ​សម្រាប់​តែ​កញ្ចប់​បាន​ដំឡើង​ក្នុង /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"រក​មិន​ឃើញ​កញ្ចប់​ដែល​ផ្ដល់​សកម្មភាព FACTORY_TEST ។"</string>
-    <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់​ផ្ដើម​ឡើង​វិញ​"</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"ចាប់​ផ្ដើម​ឡើង​វិញ"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"ទំព័រ​មាន​ចំណងជើង \"<xliff:g id="TITLE">%s</xliff:g>\" សរសេរ៖"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"បញ្ជាក់​ការ​រុករក"</string>
@@ -1019,7 +1019,7 @@
     <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="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>
@@ -1103,18 +1103,18 @@
     <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="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="minute" msgid="9148878657703769868">"នាទី"</string>
     <string name="minutes" msgid="5646001005827034509">"នាទី"</string>
-    <string name="second" msgid="3184235808021478">"វិនាទី​"</string>
+    <string name="second" msgid="3184235808021478">"វិនាទី"</string>
     <string name="seconds" msgid="3161515347216589235">"វិនាទី"</string>
-    <string name="week" msgid="5617961537173061583">"សប្ដាហ៍​"</string>
-    <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍​"</string>
-    <string name="year" msgid="4001118221013892076">"ឆ្នាំ​"</string>
-    <string name="years" msgid="6881577717993213522">"ឆ្នាំ​"</string>
+    <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>
@@ -1130,12 +1130,12 @@
     <string name="VideoView_error_title" msgid="3534509135438353077">"បញ្ហា​វីដេអូ"</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"វីដេអូ​នេះ​មិន​ត្រឹមត្រូវ​សម្រាប់​​ចរន្ត​ចូល​ឧបករណ៍​នេះ។"</string>
     <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"មិន​អាច​ចាក់​វីដេអូ​នេះ។"</string>
-    <string name="VideoView_error_button" msgid="2822238215100679592">"យល់​ព្រម​"</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"យល់​ព្រម"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"រសៀល"</string>
     <string name="Noon" msgid="3342127745230013127">"រសៀល"</string>
     <string name="midnight" msgid="7166259508850457595">"កណ្ដាលអធ្រាត្រ"</string>
-    <string name="Midnight" msgid="5630806906897892201">"កណ្ដាល​អធ្រាត្រ​"</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>
@@ -1152,13 +1152,13 @@
     <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_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="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>
@@ -1167,7 +1167,7 @@
     <string name="whichHomeApplication" msgid="4616420172727326782">"ជ្រើស​កម្មវិធី​ដើម"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​សកម្មភាព​នេះ។"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"សម្អាត​លំនាំដើម​ក្នុង​ការកំណត់​ប្រព័ន្ធ &gt; កម្មវិធី &gt; ទាញ​យក។"</string>
-    <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើស​សកម្មភាព​​"</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើស​សកម្មភាព"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"ជ្រើស​កម្មវិធី​សម្រាប់​ឧបករណ៍​យូអេសប៊ី"</string>
     <string name="noApplications" msgid="2991814273936504689">"គ្មាន​កម្មវិធី​អាច​អនុវត្ត​សកម្មភាព​នេះ។"</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
@@ -1178,7 +1178,7 @@
     <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="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>
@@ -1260,19 +1260,19 @@
     <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>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"កុំ​អនុញ្ញាត"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"បាន​ដក​ស៊ីម​កាត​ចេញ"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញ​ចល័ត​នឹង​ប្រើ​លែង​បាន​រហូត​ដល់​អ្នក​ចាប់ផ្ដើម​ជា​មួយ​ស៊ីម​កាត​ដែល​បា​បញ្ចូល​ត្រឹមត្រូវ។​"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញ​ចល័ត​នឹង​ប្រើ​លែង​បាន​រហូត​ដល់​អ្នក​ចាប់ផ្ដើម​ជា​មួយ​ស៊ីម​កាត​ដែល​បា​បញ្ចូល​ត្រឹមត្រូវ។"</string>
     <string name="sim_done_button" msgid="827949989369963775">"រួចរាល់"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"បាន​បន្ថែម​ស៊ីម​កាត"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"ចាប់ផ្ដើម​ឧបករណ៍​របស់​អ្នក​ឡើង​វិញ ដើម្បី​ចូល​ដំណើរការ​បណ្ដាញ​ចល័ត។"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"ចាប់ផ្ដើម​ឡើងវិញ"</string>
-    <string name="time_picker_dialog_title" msgid="8349362623068819295">"កំណត់​ម៉ោង​"</string>
-    <string name="date_picker_dialog_title" msgid="5879450659453782278">"កំណត់​កាល​បរិច្ឆេទ​"</string>
+    <string name="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>
@@ -1350,7 +1350,7 @@
     <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="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​សុវត្ថិភាព"</string>
     <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ឲ្យ​កម្មវិធី​ចូល​​ការ​ផ្ទុក​មាន​សុវត្ថិភាព keguard ។"</string>
     <string name="permlab_control_keyguard" msgid="172195184207828387">"ពិនិត្យ​ការ​បង្ហាញ និង​លាក់​ការ​ការពារ"</string>
     <string name="permdesc_control_keyguard" msgid="3043732290518629061">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង keguard ។"</string>
@@ -1367,7 +1367,7 @@
     <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_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>
@@ -1376,7 +1376,7 @@
     <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="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>
@@ -1399,12 +1399,12 @@
     <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_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="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>
@@ -1430,7 +1430,7 @@
     <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​បច្ចុប្បន្ន​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ។"</string>
     <string name="media_shared" product="default" msgid="5706130568133540435">"បច្ចុប្បន្ន​កាត​អេសឌី​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ"</string>
     <string name="media_unknown_state" msgid="729192782197290385">"មិន​ស្គាល់​ស្ថានភាព​មេឌៀ​ខាង​ក្រៅ។"</string>
-    <string name="share" msgid="1778686618230011964">"ចែក​រំលែក​"</string>
+    <string name="share" msgid="1778686618230011964">"ចែក​រំលែក"</string>
     <string name="find" msgid="4808270900322985960">"រក"</string>
     <string name="websearch" msgid="4337157977400211589">"ស្វែងរក​តាម​បណ្ដាញ"</string>
     <string name="find_next" msgid="5742124618942193978">"រក​បន្ទាប់"</string>
@@ -1446,7 +1446,7 @@
     <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_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>
@@ -1465,15 +1465,15 @@
     <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">"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" msgid="806688056141131819">"ចែករំលែក​ជា​មួយ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ចែក​រំលែក​ជា​មួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"គ្រប់គ្រង​ការ​រុញ។ ប៉ះ &amp; សង្កត់។"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស​ ដើម្បី​ដោះ​សោ។"</string>
@@ -1487,7 +1487,7 @@
     <string name="storage_internal" msgid="4891916833657929263">"ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"កាត​អេសឌី"</string>
     <string name="storage_usb" msgid="3017954059538517278">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
-    <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល​"</string>
+    <string name="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>
@@ -1544,7 +1544,7 @@
     <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_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>
@@ -1576,7 +1576,7 @@
     <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_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>
@@ -1685,7 +1685,7 @@
     <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
     <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"​មិន​ស្គាល់​បញ្ឈរ"</string>
     <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"មិន​ស្គាល់​ទេសភាព"</string>
-    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បាន​បោះ​បង់​"</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="reason_service_unavailable" msgid="7824008732243903268">"មិន​បា​ន​បើក​សេវាកម្ម​បោះពុម្ព"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 77e83dd..db02343 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"개인"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"직장"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"개인 앱"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"요금이 부과되는 서비스"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"요금이 부과될 수 있는 작업을 수행할 수 있도록 합니다."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"메시지"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"애플리케이션의 예약된 백그라운드 작업 실행"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"이 권한을 부여하면 요청이 있을 경우 Android 시스템이 백그라운드에서 애플리케이션을 실행할 수 있게 됩니다."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"진단 그룹 소유의 리소스 읽기/쓰기"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"앱이 진단 그룹 소유의 리소스(예: /dev에 있는 파일)를 읽고 쓸 수 있도록 허용합니다. 이 기능은 시스템 안정성 및 보안에 영향을 미칠 수 있으므로 제조업체 또는 사업자가 하드웨어 관련 진단을 수행하는 경우에만 사용해야 합니다."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"앱 구성요소 사용 또는 사용 안함"</string>
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
deleted file mode 100644
index 8c8f86c..0000000
--- a/core/res/res/values-large/themes.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<!--
-===============================================================
-                        PLEASE READ
-===============================================================
-
-The Holo 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>
-    <style name="Theme.Holo.DialogWhenLarge"
-            parent="@android:style/Theme.Holo.Dialog.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Holo.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Holo.Dialog.NoActionBar.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Holo.Light.DialogWhenLarge"
-            parent="@android:style/Theme.Holo.Light.Dialog.FixedSize">
-    </style>
-    <style name="Theme.Holo.Light.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Holo.Light.Dialog.NoActionBar.FixedSize">
-    </style>
-
-    <style name="Theme.Material.DialogWhenLarge"
-            parent="@android:style/Theme.Material.Dialog.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Material.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Material.Dialog.NoActionBar.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Material.Light.DialogWhenLarge"
-            parent="@android:style/Theme.Material.Light.Dialog.FixedSize">
-    </style>
-    <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Material.Light.Dialog.NoActionBar.FixedSize">
-    </style>
-</resources>
diff --git a/core/res/res/values-large/themes_device_defaults.xml b/core/res/res/values-large/themes_device_defaults.xml
index d57e827..d252c27 100644
--- a/core/res/res/values-large/themes_device_defaults.xml
+++ b/core/res/res/values-large/themes_device_defaults.xml
@@ -31,18 +31,12 @@
 ===============================================================
  -->
 <resources>
-    <style name="Theme.DeviceDefault.DialogWhenLarge"
-            parent="@android:style/Theme.DeviceDefault.Dialog.FixedSize">
+    <style name="Theme.DeviceDefault.DialogWhenLarge" parent="@style/Theme.DeviceDefault.Dialog.FixedSize">
         <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
     </style>
-    <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
+    <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="@style/Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
         <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
     </style>
-    <style name="Theme.DeviceDefault.Light.DialogWhenLarge"
-            parent="@android:style/Theme.DeviceDefault.Light.Dialog.FixedSize">
-    </style>
-    <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize">
-    </style>
+    <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="@style/Theme.DeviceDefault.Light.Dialog.FixedSize" />
+    <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize" />
 </resources>
diff --git a/core/res/res/values-large/themes_holo.xml b/core/res/res/values-large/themes_holo.xml
new file mode 100644
index 0000000..3f03932
--- /dev/null
+++ b/core/res/res/values-large/themes_holo.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!--
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Holo 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>
+    <style name="Theme.Holo.DialogWhenLarge" parent="@style/Theme.Holo.Dialog.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Holo.DialogWhenLarge.NoActionBar" parent="@style/Theme.Holo.Dialog.NoActionBar.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Holo.Light.DialogWhenLarge" parent="@style/Theme.Holo.Light.Dialog.FixedSize" />
+    <style name="Theme.Holo.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Holo.Light.Dialog.NoActionBar.FixedSize" />
+</resources>
diff --git a/core/res/res/values-large/themes_material.xml b/core/res/res/values-large/themes_material.xml
new file mode 100644
index 0000000..2781608
--- /dev/null
+++ b/core/res/res/values-large/themes_material.xml
@@ -0,0 +1,40 @@
+<?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 Material 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>
+    <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material.Dialog.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Dialog.NoActionBar.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light.Dialog.FixedSize" />
+    <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Light.Dialog.NoActionBar.FixedSize" />
+</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 17a4236..0e7f0c3 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
     <string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"​ສ່ວນ​ໂຕ"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"​ບ່ອນ​ເຮັດ​ວຽກ"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"​ແອັບຯ​ສ່ວນ​ໂຕ"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"ບໍລິການທີ່ເຮັດໃຫ້ທ່ານເສຍເງິນ"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ເຮັດສິ່ງທີ່ທ່ານຕ້ອງເສຍຄ່າໃຊ້ຈ່າຍ."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"ຂໍ້ຄວາມຂອງທ່ານ"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"ເປີດ​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​​ເພື່ອ​ເຮັດ​ວຽກ​ຕາມ​ເວ​ລາ​ຢູ່ໃນ​ພື້ນຫຼັງ"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"​ສິດ​ນີ້​ອະ​ນຸ​ຍາດ​ໃຫ້​ລະ​ບົບ Android ສາ​ມາດ​ເປີດ​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ໃນ​ພື້ນຫຼັງ​ເມື່ອ​ຖືກ​ຮ້ອງ​ຂໍ​ໄດ້."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ອ່ານ/ຂຽນ ໃສ່ຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິໄຈ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອ່ານ ແລະຂຽນ ໃສ່ທຸກຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິນິໄສ; ຕົວຢ່າງ: ໄຟລ໌ໃນ /dev. ສິ່ງນີ້ອາດສົ່ງຜົນກະທົບຕໍ່ຄວາມສະຖຽນ ແລະຄວາມປອດໄພຂອງລະບົບ. ສິ່ງນີ້ຄວນໃຊ້ສຳຫຼັບການວິເຄາະບັນຫາຈຳເພາະ ຂອງບາງຮາດແວໂດຍຜູ່ຜະລິດ ຫຼືຜູ່ປະຕິບັດການເທົ່ານັ້ນ."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ເປີດ ຫຼືປິດນຳໃຊ້ອົງປະກອບຂອງແອັບຯ"</string>
@@ -1697,7 +1697,7 @@
     <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_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">
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 2cd171e..e9b1247 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string>
     <string name="android_system_label" msgid="6577375335728551336">"„Android“ sistema"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Asmeninė"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Darbo"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Asmeninės programos"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"„Android“ (darbas)"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Paslaugos, už kurias mokėjote"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Atlikite mokamus veiksmus."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Jūsų pranešimai"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"vykdyti suplanuotą programos darbą fone"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Šiuo leidimu sistemai „Android“ leidžiama fone vykdyti programą, kai to prašoma."</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>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index ae037fd..8716114 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
     <string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistēma"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personisks"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Darba"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Personīgās lietotnes"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android darbs"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Maksas pakalpojumi"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Veikt darbības, par kurām, iespējams, būs jāmaksā."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Jūsu ziņojumi"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"iespējot lietojumprogrammas plānoto darbību fonā"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Ar šo atļauju Android sistēmā lietojumprogramma pēc pieprasījuma darbojas fonā."</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>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index c515b87..36d54d0 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Хувийн"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Ажил"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Хувийн апп-ууд"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Андройд Ажил"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Танаас төлбөр авдаг үйлчилгээнүүд"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Таны төлбөрт оруулах зүйлийг хийх."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Таны мессеж"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"аппликешны төлөвлөгдсөн далд ажлыг эхлүүлэх"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Энэ зөвшөөрөл нь Андройд системд төхөөрөмжийг хүсэлт гаргасан үед  аппликешныг далд ажиллуулах боломж олгоно."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"оношлох грүпийн эзэмшдэг нөөцрүү унших/бичих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Апп нь оношлох грүпийн эзэмшдэг, жишээ нь /dev доторх файлууд, дурын  нөөцийг унших бичих боломжтой.Энэ нь системийн тогвортой байдал болон аюулгүй байдалд бодитоор нөлөөлнө. Энэ нь үйлдвэрлэгч болон операторын хардверт-зориулсан оношлогоонд ашиглагдана."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"апп компонентыг идэвхжүүлэх эсвэл идэвхгүй болгох"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 637b542..e9d1e80 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"Peribadi"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Tempat Kerja"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Apl peribadi"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Kerja 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>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"jalankan kerja latar belakang dijadualkan aplikasi"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Kebenaran ini membolehkan sistem Android menjalankan aplikasi di latar belakang apabila diminta."</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>
@@ -521,7 +521,7 @@
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Pengesanan sebutan laluan"</string>
     <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Benarkan apl merakam audio untuk pengesahan Sebutan Laluan. Rakaman ini boleh berlaku di latar belakang tetapi tidak menghalang rakaman audio lain (cth. Kamkorder)."</string>
     <string name="permlab_modifyAudioRouting" msgid="7738060354490807723">"Penghalaan Audio"</string>
-    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"Membenarkan apl untuk mengawal penghalaan audio secara langsung dan mengatasi keputusan dasar audio."</string>
+    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"Membenarkan apl untuk mengawal penghalaan audio secara langsung dan melangkau keputusan dasar audio."</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tangkap output video"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Membenarkan apl menangkap dan mengubah hala output video."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tangkap output video selamat"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 62db1da..8dace09 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personlig"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Jobb"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Personlige apper"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Betaltjenester"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Gjøre ting som kan koste deg penger."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Meldinger"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"kjøre appens planlagte bakgrunnsprosesser"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Denne tillatelsen gjør at Android-systemet kan kjøre appen i bakgrunnen når det bes om det."</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>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1cc6918..a1a5357 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
     <string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-systeem"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Persoonlijk"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Persoonlijke apps"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android werk"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services waarvoor u moet betalen"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Activiteiten uitvoeren waarvoor kosten in rekening kunnen worden gebracht."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Uw berichten"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"geplande achtergrondwerkzaamheden van de app uitvoeren"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Met dit recht kan het Android-systeem de app op de achtergrond uitvoeren wanneer dit wordt gevraagd."</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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 5a75c342..76f1521 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string>
     <string name="android_system_label" msgid="6577375335728551336">"System Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Osobiste"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Praca"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplikacje osobiste"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android w pracy"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Usługi płatne"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Wykonywanie czynności, za które pobierana jest opłata."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Twoje wiadomości"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"uruchom zaplanowane działania aplikacji w tle"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"To uprawnienie zezwala Androidowi na uruchamianie aplikacji w tle na jej żądanie."</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>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 85a7a7e..471e41f 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplicações pessoais"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Trabalho Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Serviços que implicam pagamento"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Efetuar ações que implicam pagamento."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"As suas mensagens"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"executar o trabalho em segundo plano da aplicação"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Esta autorização permite ao sistema Android executar a aplicação em segundo plano quando solicitado."</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>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index cd30e91..0ed34e2 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplicativos pessoais"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android para trabalho"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Serviços que geram gastos"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Faça coisas que podem custar dinheiro."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Suas mensagens"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"executar as operações programadas do aplicativo em segundo plano"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Esta permissão permite ao sistema Android executar o aplicativo em segundo plano quando solicitado."</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>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 994b8f2..c1341c2 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -246,9 +246,9 @@
     <skip />
     <string name="safeMode" msgid="2788228061547930246">"Modus segirà"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
-    <!-- no translation found for user_owner_label (2804351898001038951) -->
+    <!-- no translation found for user_owner_label (6465364741001216388) -->
     <skip />
-    <!-- no translation found for managed_profile_label (6260850669674791528) -->
+    <!-- no translation found for managed_profile_label (4287077106125758391) -->
     <skip />
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servetschs che custan"</string>
     <!-- no translation found for permgroupdesc_costMoney (3293301903409869495) -->
@@ -722,9 +722,9 @@
     <skip />
     <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
     <skip />
-    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <!-- no translation found for permlab_bindJobService (3637568367978271086) -->
     <skip />
-    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <!-- no translation found for permdesc_bindJobService (3473288460524119838) -->
     <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leger/scriver en resursas che appartegnan a diagnostics"</string>
     <!-- no translation found for permdesc_diagnostic (6608295692002452283) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index eb56be3..ef5a384 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistemul Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Serviciu"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Aplicații personale"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android pentru serviciu"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servicii cu plată"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Efectuează acţiuni care sunt cu plată."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Mesajele dvs."</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"rulează operațiile programate, în fundal, ale aplicației"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Cu această permisiune, sistemul Android poate rula aplicația în fundal la cerere."</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>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 52dce95..ac68bda 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Личные данные"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Работа"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Персональные приложения"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android для бизнеса"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Платные услуги"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Приложение сможет использовать платные услуги."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Сообщения"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"Запуск приложения в фоновом режиме по расписанию"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Запуск приложения в фоновом режиме по запросу."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Чтение/запись данных в системы диагностики"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Приложение сможет считывать и записывать данные системы диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Это разрешение должно использоваться ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Включение/отключение компонентов приложения"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 2ee9310..20674b0 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Osobné"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Práca"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Osobné aplikácie"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android na prácu"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Spoplatnené služby"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Vykonávanie činností, ktoré vás môžu stáť peniaze."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Vaše správy"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"spustenie naplánovanej práce aplikácie na pozadí"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Toto povolenie umožňuje systému Android spustiť na základe požiadavky aplikáciu na pozadí."</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>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 8068603..01c3d0f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
     <string name="safeMode" msgid="2788228061547930246">"Varni način"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Osebno"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Služba"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Osebne aplikacije"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android – službeno"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Plačljive storitve"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Dovolite stvari, za katere bo morda treba plačati."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Vaša sporočila"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"izvajanje načrtovanega dela aplikacije v ozadju"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"To dovoljenje sistemu Android omogoča, da na zahtevo izvaja aplikacijo v ozadju."</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>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 05d71f2..074d4f7 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"Лично"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Посао"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Личне апликације"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Услуге које се плаћају"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Покреће радње које могу да се плаћају."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Поруке"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"покретање заказаних задатака апликације у позадини"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Ова дозвола омогућава систему 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>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 1c3f560..6b5431f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personligt"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Arbetet"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Personliga appar"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android – arbete"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tjänster som kostar pengar"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Göra saker som kan kosta pengar."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Dina meddelanden"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"kör appens schemalagda bakgrundsarbete"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Med den här behörigheten får Android-systemet köra appen i bakgrunden när detta begärs."</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>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 83fe801..9c958ac 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Binafsi"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Kazini"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Programu binafsi"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Kazi ya Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Huduma ambazo zinakugharimu pesa"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Fanya mambo ambayo yanaweza kukugharimu pesa."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Ujumbe wako"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"endesha kazi ya chini chini iliyopangwa ya programu"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Idhini hii huruhusu mfumo wa Android kuendesha programu chini chini ikipokea ombi."</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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index da17704..1522f2e 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
     <string name="android_system_label" msgid="6577375335728551336">"ระบบแอนดรอยด์"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"ส่วนตัว"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"ที่ทำงาน"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"แอปส่วนตัว"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"แอนดรอยด์สำหรับการทำงาน"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"บริการที่ต้องเสียค่าใช้จ่าย"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ทำสิ่งที่คุณต้องเสียค่าใช้จ่าย"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"ข้อความของคุณ"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"เรียกใช้งานเบื้องหลังที่กำหนดเวลาไว้ของแอปพลิเคชัน"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"การอนุญาตนี้ช่วยให้ระบบแอนดรอยด์สามารถเรียกใช้แอปพลิเคชันในเบื้องหลังเมื่อได้รับคำขอ"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"อ่าน/เขียนไปยังรีซอร์สที่เป็นเจ้าของโดยกลุ่มวินิจฉัย"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"อนุญาตให้แอปพลิเคชันอ่านและเขียนไปยังทรัพยากรที่เป็นของกลุ่มวินิจฉัย เช่น ไฟล์ใน /dev การทำเช่นนี้อาจส่งผลต่อความเสถียรและความปลอดภัยของระบบ และควรใช้สำหรับการวินิจฉัยเกี่ยวกับฮาร์ดแวร์โดยเฉพาะที่ทำโดยผู้ผลิตหรือผู้ให้บริการเท่านั้น"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 3bbfc0d..330bbe7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Trabaho"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Mga personal na app"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Mga serbisyong ginagastusan mo"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Gumawa ng mga bagay na magpapagastos sa iyo."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Iyong mga mensahe"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"patakbuhin ang nakaiskedyul na paggana sa background ng application"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Nagbibigay-daan ang pahintulot na ito sa Android system na paganahin ang application sa background kapag hiniling."</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>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 76ea9e9..d235ca3 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android Sistemi"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Kişisel"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"İş"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Kişisel uygulamalar"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Size maliyet getiren hizmetler"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Size maliyet getirebilecek işlemler yapma."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Mesajlarınız"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"uygulamanın planlanan arka plan işini çalıştır"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Bu izin, istendiğinde 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>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 70f6192..ffe735c 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"Особистий профіль"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Службовий профіль"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Особисті додатки"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android для бізнесу"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Служби, які потребують оплати"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Виконувати дії, які потребують оплати."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Ваші повідомл."</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"планово запускати додаток у фоновому режимі"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Маючи цей дозвіл, система Android може запускати додаток у фоновому режимі, коли це потрібно."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"чит./зап. на ресури., якими вол. діаг."</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозволяє програмі читати та писати на будь-який ресурс, яким володіє діагностична група; наприклад, у файли в папці /dev. Це потенційно може вплинути на стабільність і безпеку системи. Потрібно використовувати ЛИШЕ для певної діагностики обладнання, яку виконує виробник чи оператор."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"вмикати чи вимикати компоненти програми"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4675f5d..11b7519 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Cá nhân"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Cơ quan"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Ứng dụng cá nhân"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Dịch vụ tính tiền của bạn"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Thực hiện những tác vụ mà bạn có thể phải trả tiền."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Tin nhắn của bạn"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"chạy công việc trong nền đã lên lịch của ứng dụng"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Quyền này cho phép hệ thống Android chạy ứng dụng trong nền khi được yêu cầu."</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>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 234b3d4..55ecc3a 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"个人"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"企业"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"个人应用"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"需要您付费的服务"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"执行可能需要您付费的操作。"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"您的信息"</string>
@@ -443,10 +443,10 @@
     <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_bindIdleService" msgid="816311765497613780">"在设备处于闲置状态时运行应用"</string>
-    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"当设备处于闲置状态时,此权限允许Android系统在后台运行该应用。"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理信任的凭据"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允许应用安装和卸载CA证书(作为信任的凭据)。"</string>
+    <string name="permlab_bindJobService" msgid="3637568367978271086">"运行应用的排定后台工作"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Android系统收到请求后会在后台运行具有此权限的应用。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"读取/写入诊断所拥有的资源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允许应用读取/写入诊断组拥有的所有资源(例如 /dev 中的文件)。这可能会影响系统的稳定性和安全性。此权限仅供制造商或运营商诊断硬件方面的问题时使用。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用组件"</string>
@@ -521,7 +521,7 @@
     <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"启动指令检测"</string>
     <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"允许应用捕获音频以便检测语音启动指令。捕获操作会在后台进行,但不会妨碍其他音频捕获工具(例如摄像机)。"</string>
     <string name="permlab_modifyAudioRouting" msgid="7738060354490807723">"音频路由"</string>
-    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"允许应用直接控制音频路由以及覆盖音频政策决策。"</string>
+    <string name="permdesc_modifyAudioRouting" msgid="7205731074267199735">"允许应用直接控制音频路由以及覆盖音频规范决策。"</string>
     <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"捕获视频输出"</string>
     <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"允许该应用捕获和重定向视频输出。"</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"捕获安全视频输出"</string>
@@ -768,7 +768,7 @@
   </string-array>
   <string-array name="imAddressTypes">
     <item msgid="1738585194601476694">"住宅"</item>
-    <item msgid="1359644565647383708">"单位"</item>
+    <item msgid="1359644565647383708">"工作"</item>
     <item msgid="7868549401053615677">"其他"</item>
     <item msgid="3145118944639869809">"自定义"</item>
   </string-array>
@@ -823,7 +823,7 @@
     <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="imTypeWork" msgid="1371489290242433090">"工作"</string>
     <string name="imTypeOther" msgid="5377007495735915478">"其他"</string>
     <string name="imProtocolCustom" msgid="6919453836618749992">"自定义"</string>
     <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index b1474e6..b58a58a 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"個人"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"公司"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"個人應用程式"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android 企業版"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"付費服務"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"執行需付費的操作或服務。"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"您的訊息"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"執行應用程式的預定背景作業"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"這項權限可讓 Android 系統於收到要求時在背景執行應用程式。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀取/寫入由診斷應用程式擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取及寫入診斷群組所擁有的任何資源 (例如:位於 /dev 中的檔案)。這可能會影響系統的穩定性及安全性,只應對製造商或網絡供應商所使用的硬件專用診斷程式開放這項權限。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 0e7bfa8..f7dae2c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -188,8 +188,8 @@
     <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="user_owner_label" msgid="2804351898001038951">"個人"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"公司"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"個人應用程式"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"Android 企業版"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"需要額外費用的服務。"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"執行需付費的作業或服務。"</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"您的簡訊"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"執行應用程式的預定背景作業"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"這項權限可讓 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>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ff1bc40..7d9e36a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -188,8 +188,8 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Imodi ephephile"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Uhlelo lwe-Android"</string>
-    <string name="user_owner_label" msgid="2804351898001038951">"Okomuntu siqu"</string>
-    <string name="managed_profile_label" msgid="6260850669674791528">"Umsebenzi"</string>
+    <string name="user_owner_label" msgid="6465364741001216388">"Izinhlelo zokusebenza zomuntu siqu"</string>
+    <string name="managed_profile_label" msgid="4287077106125758391">"I-Android Work"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Amasevisi abiza imali"</string>
     <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Yenza izinto ezingakudla imali."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Imiyalezo yakho"</string>
@@ -445,8 +445,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_bindJobService" msgid="3637568367978271086">"qalisa umsebenzi ongemuva oshejuliwe wohlelo lokusebenza"</string>
+    <string name="permdesc_bindJobService" msgid="3473288460524119838">"Le mvume ivumela isistimu ye-Android ukuthi iqalise uhlelo lokusebenza ngemuva uma icelwa."</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>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4fa04a9..ed648fb 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4669,12 +4669,8 @@
 
     <!-- Drawable used to show animated touch feedback. -->
     <declare-styleable name="RippleDrawable">
-        <!-- The tint to use for ripple effects. This attribute is required. -->
-        <attr name="tint" />
-        <!-- Specifies the Porter-Duff blending mode used to apply the tint. The default value is src_atop, which draws over the opaque parts of the drawable. -->
-        <attr name="tintMode" />
-        <!-- Whether to pin ripple effects to the center of the drawable. Default value is false. -->
-        <attr name="pinned" format="boolean" />
+        <!-- The color to use for ripple effects. This attribute is required. -->
+        <attr name="color" />
     </declare-styleable>
 
     <declare-styleable name="ScaleDrawable">
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 9bf2ce8..9f6c7ad 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -135,7 +135,6 @@
     <color name="notification_action_legacy_color_filter">#ff555555</color>
 
     <color name="notification_media_action_bg">#00000000</color>
-    <color name="notification_media_info_bg">#40FFFFFF</color>
     <color name="notification_media_progress">#FFFFFFFF</color>
 
     <!-- Keyguard colors -->
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index fdbe0a0..7371d4e 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -27,10 +27,10 @@
 
     <color name="bright_foreground_material_dark">@color/white</color>
     <color name="bright_foreground_material_light">@color/black</color>
-    <!-- Black 50% -->
-    <color name="bright_foreground_disabled_material_dark">#80000000</color>
     <!-- White 50% -->
-    <color name="bright_foreground_disabled_material_light">#80ffffff</color>
+    <color name="bright_foreground_disabled_material_dark">#80ffffff</color>
+    <!-- Black 50% -->
+    <color name="bright_foreground_disabled_material_light">#80000000</color>
     <color name="bright_foreground_inverse_material_dark">@color/bright_foreground_material_light</color>
     <color name="bright_foreground_inverse_material_light">@color/bright_foreground_material_dark</color>
 
@@ -89,6 +89,9 @@
     <color name="material_teal_A200">#ff18ffff</color>
     <color name="material_teal_A400">#ff00e5ff</color>
 
+    <!-- Accent color used by Settings -->
+    <color name="material_dark_teal_A400">#ff009688</color>
+
     <color name="material_green_100">#ffb7e1cd</color>
     <color name="material_green_300">#ff57bb8a</color>
     <color name="material_green_500">#ff0f9d58</color>
@@ -143,7 +146,10 @@
     <color name="material_blue_grey_600">#ff546e7a</color>
     <color name="material_blue_grey_700">#ff455a64</color>
     <color name="material_blue_grey_800">#ff37474f</color>
+    <!-- Primary color used by Settings -->
     <color name="material_blue_grey_900">#ff263238</color>
+    <!-- Primary dark color used by Settings -->
+    <color name="material_blue_grey_950">#ff21272b</color>
 
     <color name="material_brown_100">#ffd7ccc8</color>
     <color name="material_brown_300">#ffa1887f</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 865d92a..27ac6c30 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -589,7 +589,7 @@
 
     <!-- Display low battery warning when battery level dips to this value.
          Also, the battery stats are flushed to disk when we hit this level.  -->
-    <integer name="config_criticalBatteryWarningLevel">4</integer>
+    <integer name="config_criticalBatteryWarningLevel">5</integer>
 
     <!-- Shutdown if the battery temperature exceeds (this value * 0.1) Celsius. -->
     <integer name="config_shutdownBatteryTemperature">680</integer>
@@ -597,8 +597,9 @@
     <!-- Display low battery warning when battery level dips to this value -->
     <integer name="config_lowBatteryWarningLevel">15</integer>
 
-    <!-- Close low battery warning when battery level reaches this value -->
-    <integer name="config_lowBatteryCloseWarningLevel">20</integer>
+    <!-- Close low battery warning when battery level reaches the lowBatteryWarningLevel
+         plus this -->
+    <integer name="config_lowBatteryCloseWarningBump">5</integer>
 
     <!-- Default color for notification LED. -->
     <color name="config_defaultNotificationColor">#ffffffff</color>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b3e111b..e16082f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2132,7 +2132,6 @@
   <public type="attr" name="strokeLineJoin" />
   <public type="attr" name="clipToPath" />
   <public type="attr" name="requiredForProfile"/>
-  <public type="attr" name="pinned" />
   <public type="attr" name="colorControlNormal" />
   <public type="attr" name="colorControlActivated" />
   <public type="attr" name="colorButtonNormal" />
@@ -2193,6 +2192,8 @@
 
   <public type="style" name="Widget.FastScroll" />
   <public type="style" name="Widget.StackView" />
+  <public type="style" name="Widget.Toolbar" />
+  <public type="style" name="Widget.Toolbar.Button.Navigation" />
 
   <public type="style" name="Widget.Holo.FastScroll" />
   <public type="style" name="Widget.Holo.StackView" />
@@ -2243,6 +2244,8 @@
   <public type="style" name="TextAppearance.Material.Widget.TextView.PopupMenu" />
   <public type="style" name="TextAppearance.Material.Widget.TextView.SpinnerItem" />
 
+  <public type="style" name="Theme.DeviceDefault.Settings" />
+
   <public type="style" name="Theme.Material" />
   <public type="style" name="Theme.Material.Dialog" />
   <public type="style" name="Theme.Material.Dialog.MinWidth" />
@@ -2256,6 +2259,7 @@
   <public type="style" name="Theme.Material.NoActionBar.Overscan" />
   <public type="style" name="Theme.Material.NoActionBar.TranslucentDecor" />
   <public type="style" name="Theme.Material.Panel" />
+  <public type="style" name="Theme.Material.Settings" />
   <public type="style" name="Theme.Material.Voice" />
   <public type="style" name="Theme.Material.Wallpaper" />
   <public type="style" name="Theme.Material.Wallpaper.NoTitleBar" />
@@ -2339,6 +2343,8 @@
   <public type="style" name="Widget.Material.TabWidget" />
   <public type="style" name="Widget.Material.TextView" />
   <public type="style" name="Widget.Material.TextView.SpinnerItem" />
+  <public type="style" name="Widget.Material.Toolbar" />
+  <public type="style" name="Widget.Material.Toolbar.Button.Navigation" />
   <public type="style" name="Widget.Material.WebTextView" />
   <public type="style" name="Widget.Material.WebView" />
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d521746..1f76bb5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -460,7 +460,7 @@
     <string name="user_owner_label">Personal apps</string>
 
     <!-- Label for a corporate profile in the intent forwarding app. -->
-    <string name="managed_profile_label">Android for Work</string>
+    <string name="managed_profile_label">Android Work</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_costMoney">Services that cost you money</string>
@@ -1261,10 +1261,10 @@
          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 scheduled background work.  -->
-    <string name="permlab_bindTaskService">run the application\'s scheduled background work</string>
+    <string name="permlab_bindJobService">run the application\'s scheduled background work</string>
     <!-- Description of an application permission, so that the user can understand
          what is being done if they are curious. -->
-    <string name="permdesc_bindTaskService">This permission allows the Android system to run the application in the background when requested.</string>
+    <string name="permdesc_bindJobService">This permission allows the Android system to run the application in the background when requested.</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>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 3d73995..7120521 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -344,7 +344,9 @@
         <item name="android:textColor">#66000000</item>
     </style>
 
-    <style name="Widget.StatusBar.Material.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal">
+    <style name="Widget.StatusBar.Material.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" />
+
+    <style name="Widget.StatusBar.Material.ProgressBar.Media">
         <item name="android:progressDrawable">@drawable/notification_material_media_progress</item>
     </style>
 
@@ -646,6 +648,14 @@
         <item name="maxWidth">180dip</item>
     </style>
 
+    <style name="Widget.Material.Toolbar" parent="Widget.Toolbar">
+        <item name="android:navigationButtonStyle">@android:style/Widget.Material.Toolbar.Button.Navigation</item>
+    </style>
+
+    <style name="Widget.Material.Toolbar.Button.Navigation" parent="Widget.Toolbar.Button.Navigation">
+        <item name="android:background">?attr/selectableItemBackgroundBorderless</item>
+    </style>
+
     <style name="Widget.Material.WebTextView" parent="Widget.WebTextView"/>
 
     <style name="Widget.Material.WebView" parent="Widget.WebView"/>
@@ -952,12 +962,17 @@
     <!-- Window title -->
     <style name="WindowTitleBackground.Material">
         <item name="background">@null</item>
+        <item name="paddingStart">16dp</item>
+        <item name="paddingEnd">16dp</item>
+        <item name="paddingTop">16dp</item>
     </style>
 
     <style name="WindowTitle.Material">
         <item name="singleLine">true</item>
         <item name="textAppearance">@style/TextAppearance.Material.WindowTitle</item>
         <item name="shadowRadius">0</item>
+        <item name="ellipsize">end</item>
+        <item name="textAlignment">viewStart</item>
     </style>
 
     <style name="DialogWindowTitle.Material">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index bfdb8a4..d8e31ea 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1509,7 +1509,7 @@
   <java-symbol type="integer" name="config_defaultNotificationLedOn" />
   <java-symbol type="integer" name="config_deskDockKeepsScreenOn" />
   <java-symbol type="integer" name="config_lightSensorWarmupTime" />
-  <java-symbol type="integer" name="config_lowBatteryCloseWarningLevel" />
+  <java-symbol type="integer" name="config_lowBatteryCloseWarningBump" />
   <java-symbol type="integer" name="config_lowBatteryWarningLevel" />
   <java-symbol type="integer" name="config_networkPolicyDefaultWarning" />
   <java-symbol type="integer" name="config_networkTransitionTimeout" />
@@ -1677,7 +1677,6 @@
   <java-symbol type="drawable" name="notification_material_bg" />
   <java-symbol type="drawable" name="notification_material_media_progress" />
   <java-symbol type="color" name="notification_media_action_bg" />
-  <java-symbol type="color" name="notification_media_info_bg" />
   <java-symbol type="color" name="notification_media_progress" />
   <java-symbol type="id" name="media_action_area" />
 
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 6b7d861..27c8754 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -555,4 +555,7 @@
 
     <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar" />
 
+    <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
+    <style name="Theme.DeviceDefault.Settings" parent="Theme.Material.Settings" />
+
 </resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index c14d7fc9..97ad7e4 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -154,7 +154,7 @@
         <item name="windowContentOverlay">@null</item>
         <item name="windowShowWallpaper">false</item>
         <item name="windowTitleStyle">@style/WindowTitle.Material</item>
-        <item name="windowTitleSize">25dip</item>
+        <item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
         <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
         <item name="windowContentTransitions">false</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
@@ -321,6 +321,8 @@
         <item name="actionModeFindDrawable">@drawable/ic_menu_find_material</item>
         <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_material</item>
 
+        <item name="toolbarStyle">@style/Widget.Material.Toolbar</item>
+
         <item name="dividerVertical">?attr/listDivider</item>
         <item name="dividerHorizontal">?attr/listDivider</item>
         <item name="buttonBarStyle">@style/Widget.Material.ButtonBar</item>
@@ -501,7 +503,7 @@
         <item name="windowContentOverlay">@drawable/ab_solid_shadow_material</item>
         <item name="windowShowWallpaper">false</item>
         <item name="windowTitleStyle">@style/WindowTitle.Material</item>
-        <item name="windowTitleSize">25dip</item>
+        <item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
         <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
         <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
@@ -511,6 +513,9 @@
         <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
         <item name="statusBarColor">?attr/colorPrimaryDark</item>
         <item name="navigationBarColor">@color/black</item>
+        <item name="windowEnterTransition">@transition/fade</item>
+        <item name="windowSharedElementEnterTransition">@transition/move</item>
+        <item name="windowSharedElementExitTransition">@transition/move</item>
 
         <!-- Dialog attributes -->
         <item name="dialogTheme">@style/Theme.Material.Light.Dialog</item>
@@ -667,6 +672,8 @@
         <item name="actionModeFindDrawable">@drawable/ic_menu_find_material</item>
         <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_material</item>
 
+        <item name="toolbarStyle">@style/Widget.Material.Toolbar</item>
+
         <item name="dividerVertical">?attr/listDivider</item>
         <item name="dividerHorizontal">?attr/listDivider</item>
         <item name="buttonBarStyle">@style/Widget.Material.Light.ButtonBar</item>
@@ -1002,7 +1009,7 @@
     <style name="Theme.Material.Dialog">
         <item name="windowFrame">@null</item>
         <item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
-        <item name="windowBackground">@drawable/dialog_background_material</item>
+        <item name="windowBackground">@drawable/dialog_background_shadow_material</item>
         <item name="windowIsFloating">true</item>
         <item name="windowContentOverlay">@null</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
@@ -1098,18 +1105,15 @@
     <!-- 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.Material.DialogWhenLarge" parent="@style/Theme.Material">
-    </style>
+    <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material" />
 
     <!-- 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.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.NoActionBar">
-    </style>
+    <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.NoActionBar" />
 
     <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Material.Dialog.Presentation" parent="@style/Theme.Material.NoActionBar.Fullscreen">
-    </style>
+    <style name="Theme.Material.Dialog.Presentation" parent="@style/Theme.Material.NoActionBar.Fullscreen" />
 
     <!-- Light material dialog themes -->
 
@@ -1121,7 +1125,7 @@
     <style name="Theme.Material.Light.Dialog">
         <item name="windowFrame">@null</item>
         <item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
-        <item name="windowBackground">?attr/colorBackground</item>
+        <item name="windowBackground">@drawable/dialog_background_shadow_material</item>
         <item name="windowIsFloating">true</item>
         <item name="windowContentOverlay">@null</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
@@ -1185,15 +1189,12 @@
     <!-- 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.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light">
-    </style>
+    <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light" />
 
     <!-- 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.Material.Light.DialogWhenLarge.NoActionBar"
-            parent="@style/Theme.Material.Light.NoActionBar">
-    </style>
+    <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Light.NoActionBar" />
 
     <!-- Material light theme for alert dialog windows, which is used by the
          {@link android.app.AlertDialog} class.  This is basically a dialog
@@ -1215,8 +1216,7 @@
     </style>
 
     <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Material.Light.Dialog.Presentation" parent="@style/Theme.Material.Light.NoActionBar.Fullscreen" >
-    </style>
+    <style name="Theme.Material.Light.Dialog.Presentation" parent="@style/Theme.Material.Light.NoActionBar.Fullscreen" />
 
     <!-- Default material (dark) for windows that want to have the user's selected
          wallpaper appear behind them.  -->
@@ -1232,4 +1232,11 @@
         <item name="windowNoTitle">true</item>
     </style>
 
+    <!-- Default theme for Settings and activities launched from Settings. -->
+    <style name="Theme.Material.Settings" parent="@style/Theme.Material.Light.DarkActionBar">
+        <item name="colorPrimary">@color/material_blue_grey_900</item>
+        <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
+        <item name="colorAccent">@color/material_dark_teal_A400</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 db125e6..116a31e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -336,7 +336,7 @@
                     if (!InetAddress.isNumeric(dnsAddr)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
+                    mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
                 } catch (UnknownHostException e) {
                     throw new SAXException();
                 }
@@ -348,7 +348,7 @@
                     if (!InetAddress.isNumeric(dnsAddr)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
+                    mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
                 } catch (UnknownHostException e) {
                     throw new SAXException();
                 }
diff --git a/core/tests/coretests/src/android/net/LinkAddressTest.java b/core/tests/coretests/src/android/net/LinkAddressTest.java
index bccf5564..814ecdd 100644
--- a/core/tests/coretests/src/android/net/LinkAddressTest.java
+++ b/core/tests/coretests/src/android/net/LinkAddressTest.java
@@ -56,26 +56,26 @@
         // Valid addresses work as expected.
         address = new LinkAddress(V4_ADDRESS, 25);
         assertEquals(V4_ADDRESS, address.getAddress());
-        assertEquals(25, address.getNetworkPrefixLength());
+        assertEquals(25, address.getPrefixLength());
         assertEquals(0, address.getFlags());
         assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
 
         address = new LinkAddress(V6_ADDRESS, 127);
         assertEquals(V6_ADDRESS, address.getAddress());
-        assertEquals(127, address.getNetworkPrefixLength());
+        assertEquals(127, address.getPrefixLength());
         assertEquals(0, address.getFlags());
         assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
 
         // Nonsensical flags/scopes or combinations thereof are acceptable.
         address = new LinkAddress(V6 + "/64", IFA_F_DEPRECATED | IFA_F_PERMANENT, RT_SCOPE_LINK);
         assertEquals(V6_ADDRESS, address.getAddress());
-        assertEquals(64, address.getNetworkPrefixLength());
+        assertEquals(64, address.getPrefixLength());
         assertEquals(IFA_F_DEPRECATED | IFA_F_PERMANENT, address.getFlags());
         assertEquals(RT_SCOPE_LINK, address.getScope());
 
         address = new LinkAddress(V4 + "/23", 123, 456);
         assertEquals(V4_ADDRESS, address.getAddress());
-        assertEquals(23, address.getNetworkPrefixLength());
+        assertEquals(23, address.getPrefixLength());
         assertEquals(123, address.getFlags());
         assertEquals(456, address.getScope());
 
@@ -94,10 +94,10 @@
         }
 
         assertEquals(NetworkUtils.numericToInetAddress("127.0.0.1"), ipv4Loopback.getAddress());
-        assertEquals(8, ipv4Loopback.getNetworkPrefixLength());
+        assertEquals(8, ipv4Loopback.getPrefixLength());
 
         assertEquals(NetworkUtils.numericToInetAddress("::1"), ipv6Loopback.getAddress());
-        assertEquals(128, ipv6Loopback.getNetworkPrefixLength());
+        assertEquals(128, ipv6Loopback.getPrefixLength());
 
         // Null addresses are rejected.
         try {
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index 553afe0..e649baa 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -88,8 +88,8 @@
             source.addLinkAddress(LINKADDRV4);
             source.addLinkAddress(LINKADDRV6);
             // set 2 dnses
-            source.addDns(DNS1);
-            source.addDns(DNS2);
+            source.addDnsServer(DNS1);
+            source.addDnsServer(DNS2);
             // set 2 gateways
             source.addRoute(new RouteInfo(GATEWAY1));
             source.addRoute(new RouteInfo(GATEWAY2));
@@ -101,8 +101,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -114,8 +114,8 @@
             target.setInterfaceName("qmi1");
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -127,8 +127,8 @@
             target.addLinkAddress(new LinkAddress(
                     NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -139,8 +139,8 @@
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
             // change dnses
-            target.addDns(NetworkUtils.numericToInetAddress("75.208.7.2"));
-            target.addDns(DNS2);
+            target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -150,8 +150,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             // change gateway
             target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
             target.addRoute(new RouteInfo(GATEWAY2));
@@ -162,8 +162,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             // change mtu
@@ -185,8 +185,8 @@
             source.addLinkAddress(LINKADDRV4);
             source.addLinkAddress(LINKADDRV6);
             // set 2 dnses
-            source.addDns(DNS1);
-            source.addDns(DNS2);
+            source.addDnsServer(DNS1);
+            source.addDnsServer(DNS2);
             // set 2 gateways
             source.addRoute(new RouteInfo(GATEWAY1));
             source.addRoute(new RouteInfo(GATEWAY2));
@@ -197,8 +197,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV6);
             target.addLinkAddress(LINKADDRV4);
-            target.addDns(DNS2);
-            target.addDns(DNS1);
+            target.addDnsServer(DNS2);
+            target.addDnsServer(DNS1);
             target.addRoute(new RouteInfo(GATEWAY2));
             target.addRoute(new RouteInfo(GATEWAY1));
             target.setMtu(MTU);
diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java
index 55d6592..c80d0bf 100644
--- a/core/tests/coretests/src/android/net/RouteInfoTest.java
+++ b/core/tests/coretests/src/android/net/RouteInfoTest.java
@@ -43,17 +43,17 @@
 
         // Invalid input.
         try {
-            r = new RouteInfo(null, null, "rmnet0");
+            r = new RouteInfo((LinkAddress) null, null, "rmnet0");
             fail("Expected RuntimeException:  destination and gateway null");
         } catch(RuntimeException e) {}
 
         // Null destination is default route.
-        r = new RouteInfo(null, Address("2001:db8::1"), null);
+        r = new RouteInfo((LinkAddress) null, Address("2001:db8::1"), null);
         assertEquals(Prefix("::/0"), r.getDestination());
         assertEquals(Address("2001:db8::1"), r.getGateway());
         assertNull(r.getInterface());
 
-        r = new RouteInfo(null, Address("192.0.2.1"), "wlan0");
+        r = new RouteInfo((LinkAddress) null, Address("192.0.2.1"), "wlan0");
         assertEquals(Prefix("0.0.0.0/0"), r.getDestination());
         assertEquals(Address("192.0.2.1"), r.getGateway());
         assertEquals("wlan0", r.getInterface());
@@ -71,17 +71,19 @@
     }
 
     public void testMatches() {
-        class PatchedRouteInfo extends RouteInfo {
+        class PatchedRouteInfo {
+            private final RouteInfo mRouteInfo;
+
             public PatchedRouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
-                super(destination, gateway, iface);
+                mRouteInfo = new RouteInfo(destination, gateway, iface);
             }
 
             public boolean matches(InetAddress destination) {
-                return super.matches(destination);
+                return mRouteInfo.matches(destination);
             }
         }
 
-        RouteInfo r;
+        PatchedRouteInfo r;
 
         r = new PatchedRouteInfo(Prefix("2001:db8:f00::ace:d00d/127"), null, "rmnet0");
         assertTrue(r.matches(Address("2001:db8:f00::ace:d00c")));
@@ -96,11 +98,11 @@
         assertFalse(r.matches(Address("192.0.0.21")));
         assertFalse(r.matches(Address("8.8.8.8")));
 
-        RouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0");
+        PatchedRouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0");
         assertTrue(ipv6Default.matches(Address("2001:db8::f00")));
         assertFalse(ipv6Default.matches(Address("192.0.2.1")));
 
-        RouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0");
+        PatchedRouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0");
         assertTrue(ipv4Default.matches(Address("255.255.255.255")));
         assertTrue(ipv4Default.matches(Address("192.0.2.1")));
         assertFalse(ipv4Default.matches(Address("2001:db8::f00")));
diff --git a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
index 7d72f3e..d850c7c 100644
--- a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
+++ b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
@@ -21,7 +21,7 @@
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.inputmethod.CursorAnchorInfo;
-import android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder;
+import android.view.inputmethod.CursorAnchorInfo.Builder;
 
 public class CursorAnchorInfoTest extends InstrumentationTestCase {
     // null represents a character that is invisible, for example because it's overlapped by some
@@ -64,7 +64,7 @@
         Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
         TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
 
-        final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
+        final Builder builder = new Builder();
         builder.setSelectionRange(SELECTION_START, SELECTION_END)
                 .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
                 .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
@@ -148,7 +148,7 @@
         final Matrix MATRIX3 = new Matrix();
         MATRIX3.setTranslate(210.0f, 220.0f);
         final Matrix matrix = new Matrix();
-        final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
+        final Builder builder = new Builder();
 
         matrix.set(MATRIX1);
         builder.setMatrix(matrix);
@@ -171,7 +171,7 @@
     public void testBuilderAdd() throws Exception {
         // A negative index should be rejected.
         try {
-            new CursorAnchorInfoBuilder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
+            new Builder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
         } catch (IllegalArgumentException ex) {
             assertTrue(true);
         }
@@ -191,4 +191,3 @@
         }
     }
 }
-
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java
index 4623fa8..345400e 100644
--- a/graphics/java/android/graphics/drawable/Ripple.java
+++ b/graphics/java/android/graphics/drawable/Ripple.java
@@ -38,15 +38,18 @@
  */
 class Ripple {
     private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
-    private static final TimeInterpolator DECEL_INTERPOLATOR = new DecelerateInterpolator(4);
+    private static final TimeInterpolator DECEL_INTERPOLATOR = new LogInterpolator();
 
     private static final float GLOBAL_SPEED = 1.0f;
     private static final float WAVE_TOUCH_DOWN_ACCELERATION = 1024.0f * GLOBAL_SPEED;
-    private static final float WAVE_TOUCH_UP_ACCELERATION = 3096.0f * GLOBAL_SPEED;
-    private static final float WAVE_OPACITY_DECAY_VELOCITY = 1.9f / GLOBAL_SPEED;
-    private static final float WAVE_OUTER_OPACITY_VELOCITY = 1.2f * GLOBAL_SPEED;
+    private static final float WAVE_TOUCH_UP_ACCELERATION = 3400.0f * GLOBAL_SPEED;
+    private static final float WAVE_OPACITY_DECAY_VELOCITY = 3.0f / GLOBAL_SPEED;
+    private static final float WAVE_OUTER_OPACITY_VELOCITY_MAX = 4.5f * GLOBAL_SPEED;
+    private static final float WAVE_OUTER_OPACITY_VELOCITY_MIN = 1.5f * GLOBAL_SPEED;
+    private static final float WAVE_OUTER_SIZE_INFLUENCE_MAX = 200f;
+    private static final float WAVE_OUTER_SIZE_INFLUENCE_MIN = 40f;
 
-    private static final long RIPPLE_ENTER_DELAY = 100;
+    private static final long RIPPLE_ENTER_DELAY = 80;
 
     // Hardware animators.
     private final ArrayList<RenderNodeAnimator> mRunningAnimations = new ArrayList<>();
@@ -68,6 +71,8 @@
 
     private float mStartingX;
     private float mStartingY;
+    private float mClampedStartingX;
+    private float mClampedStartingY;
 
     // Hardware rendering properties.
     private CanvasProperty<Paint> mPropPaint;
@@ -112,6 +117,7 @@
     public Ripple(RippleDrawable owner, Rect bounds, float startingX, float startingY) {
         mOwner = owner;
         mBounds = bounds;
+
         mStartingX = startingX;
         mStartingY = startingY;
     }
@@ -131,6 +137,23 @@
         mOuterX = 0;
         mOuterY = 0;
         mDensity = density;
+
+        clampStartingPosition();
+    }
+
+    private void clampStartingPosition() {
+        final float dX = mStartingX - mBounds.exactCenterX();
+        final float dY = mStartingY - mBounds.exactCenterY();
+        final float r = mOuterRadius;
+        if (dX * dX + dY * dY > r * r) {
+            // Point is outside the circle, clamp to the circumference.
+            final double angle = Math.atan2(dY, dX);
+            mClampedStartingX = (float) (Math.cos(angle) * r);
+            mClampedStartingY = (float) (Math.sin(angle) * r);
+        } else {
+            mClampedStartingX = mStartingX;
+            mClampedStartingY = mStartingY;
+        }
     }
 
     public void onHotspotBoundsChanged() {
@@ -138,6 +161,8 @@
             final float halfWidth = mBounds.width() / 2.0f;
             final float halfHeight = mBounds.height() / 2.0f;
             mOuterRadius = (float) Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight);
+
+            clampStartingPosition();
         }
     }
 
@@ -247,8 +272,10 @@
         final int alpha = (int) (paintAlpha * mOpacity + 0.5f);
         final float radius = MathUtils.lerp(0, mOuterRadius, mTweenRadius);
         if (alpha > 0 && radius > 0) {
-            final float x = MathUtils.lerp(mStartingX - mBounds.exactCenterX(), mOuterX, mTweenX);
-            final float y = MathUtils.lerp(mStartingY - mBounds.exactCenterY(), mOuterY, mTweenY);
+            final float x = MathUtils.lerp(
+                    mClampedStartingX - mBounds.exactCenterX(), mOuterX, mTweenX);
+            final float y = MathUtils.lerp(
+                    mClampedStartingY - mBounds.exactCenterY(), mOuterY, mTweenY);
             p.setAlpha(alpha);
             p.setStyle(Style.FILL);
             c.drawCircle(x, y, radius, p);
@@ -277,6 +304,8 @@
     public void move(float x, float y) {
         mStartingX = x;
         mStartingY = y;
+
+        clampStartingPosition();
     }
 
     /**
@@ -285,7 +314,7 @@
     public void enter() {
         final int radiusDuration = (int)
                 (1000 * Math.sqrt(mOuterRadius / WAVE_TOUCH_DOWN_ACCELERATION * mDensity) + 0.5);
-        final int outerDuration = (int) (1000 * 1.0f / WAVE_OUTER_OPACITY_VELOCITY);
+        final int outerDuration = (int) (1000 * 1.0f / WAVE_OUTER_OPACITY_VELOCITY_MIN);
 
         final ObjectAnimator radius = ObjectAnimator.ofFloat(this, "radiusGravity", 1);
         radius.setAutoCancel(true);
@@ -329,7 +358,6 @@
      */
     public void exit() {
         cancelSoftwareAnimations();
-
         final float radius = MathUtils.lerp(0, mOuterRadius, mTweenRadius);
         final float remaining;
         if (mAnimRadius != null && mAnimRadius.isRunning()) {
@@ -342,13 +370,23 @@
                 + WAVE_TOUCH_DOWN_ACCELERATION) * mDensity) + 0.5);
         final int opacityDuration = (int) (1000 * mOpacity / WAVE_OPACITY_DECAY_VELOCITY + 0.5f);
 
+        // Scale the outer max opacity and opacity velocity based
+        // on the size of the outer radius
+
+        float outerSizeInfluence = MathUtils.constrain(
+                (mOuterRadius - WAVE_OUTER_SIZE_INFLUENCE_MIN * mDensity)
+                / (WAVE_OUTER_SIZE_INFLUENCE_MAX * mDensity), 0, 1);
+        float outerOpacityVelocity = MathUtils.lerp(WAVE_OUTER_OPACITY_VELOCITY_MIN,
+                WAVE_OUTER_OPACITY_VELOCITY_MAX, outerSizeInfluence);
+
         // Determine at what time the inner and outer opacity intersect.
         // inner(t) = mOpacity - t * WAVE_OPACITY_DECAY_VELOCITY / 1000
         // outer(t) = mOuterOpacity + t * WAVE_OUTER_OPACITY_VELOCITY / 1000
+
         final int outerInflection = Math.max(0, (int) (1000 * (mOpacity - mOuterOpacity)
-                / (WAVE_OPACITY_DECAY_VELOCITY + WAVE_OUTER_OPACITY_VELOCITY) + 0.5f));
+                / (WAVE_OPACITY_DECAY_VELOCITY + outerOpacityVelocity) + 0.5f));
         final int inflectionOpacity = (int) (255 * (mOuterOpacity + outerInflection
-                * WAVE_OUTER_OPACITY_VELOCITY / 1000) + 0.5f);
+                * outerOpacityVelocity * outerSizeInfluence / 1000) + 0.5f);
 
         if (mCanUseHardware) {
             exitHardware(radiusDuration, opacityDuration, outerInflection, inflectionOpacity);
@@ -361,8 +399,10 @@
             int inflectionOpacity) {
         mPendingAnimations.clear();
 
-        final float startX = MathUtils.lerp(mStartingX - mBounds.exactCenterX(), mOuterX, mTweenX);
-        final float startY = MathUtils.lerp(mStartingY - mBounds.exactCenterY(), mOuterY, mTweenY);
+        final float startX = MathUtils.lerp(
+                mClampedStartingX - mBounds.exactCenterX(), mOuterX, mTweenX);
+        final float startY = MathUtils.lerp(
+                mClampedStartingY - mBounds.exactCenterY(), mOuterY, mTweenY);
         final Paint outerPaint = new Paint();
         outerPaint.setAntiAlias(true);
         outerPaint.setColor(mColor);
@@ -578,4 +618,14 @@
             removeSelf();
         }
     };
+
+    /**
+    * Interpolator with a smooth log deceleration
+    */
+    private static final class LogInterpolator implements TimeInterpolator {
+        @Override
+        public float getInterpolation(float input) {
+            return 1 - (float) Math.pow(400, -input * 1.4);
+        }
+    }
 }
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index e37fbeb..0512ecc 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -48,22 +48,41 @@
  * A touch feedback drawable may contain multiple child layers, including a
  * special mask layer that is not drawn to the screen. A single layer may be set
  * as the mask by specifying its android:id value as {@link android.R.id#mask}.
+ * <pre>
+ * <code>&lt!-- A red ripple masked against an opaque rectangle. --/>
+ * &ltripple android:color="#ffff0000">
+ *   &ltitem android:id="@android:id/mask"
+ *         android:drawable="#ffffffff" />
+ * &ltripple /></code>
+ * </pre>
  * <p>
  * If a mask layer is set, the ripple effect will be masked against that layer
- * before it is blended onto the composite of the remaining child layers.
+ * before it is drawn over the composite of the remaining child layers.
  * <p>
- * If no mask layer is set, the ripple effect is simply blended onto the
- * composite of the child layers using the specified
- * {@link android.R.styleable#RippleDrawable_tintMode}.
+ * If no mask layer is set, the ripple effect is masked against the composite
+ * of the child layers.
+ * <pre>
+ * <code>&lt!-- A blue ripple drawn atop a green rectangle. --/>
+ * &ltripple android:color="#ff00ff00">
+ *   &ltitem android:drawable="#ff0000ff" />
+ * &ltripple />
+ *
+ * &lt!-- A red ripple drawn atop a drawable resource. --/>
+ * &ltripple android:color="#ff00ff00">
+ *   &ltitem android:drawable="@drawable/my_drawable" />
+ * &ltripple /></code>
+ * </pre>
  * <p>
  * If no child layers or mask is specified and the ripple is set as a View
- * background, the ripple will be blended onto the first available parent
- * background within the View's hierarchy using the specified
- * {@link android.R.styleable#RippleDrawable_tintMode}. In this case, the
- * drawing region may extend outside of the Drawable bounds.
+ * background, the ripple will be drawn atop the first available parent
+ * background within the View's hierarchy. In this case, the drawing region
+ * may extend outside of the Drawable bounds.
+ * <pre>
+ * <code>&lt!-- An unbounded green ripple. --/>
+ * &ltripple android:color="#ff0000ff" /></code>
+ * </pre>
  *
- * @attr ref android.R.styleable#DrawableStates_state_focused
- * @attr ref android.R.styleable#DrawableStates_state_pressed
+ * @attr ref android.R.styleable#RippleDrawable_color
  */
 public class RippleDrawable extends LayerDrawable {
     private static final String LOG_TAG = RippleDrawable.class.getSimpleName();
@@ -188,8 +207,8 @@
         setActive(active && enabled);
 
         // Update the paint color. Only applicable when animated in software.
-        if (mRipplePaint != null && mState.mTint != null) {
-            final ColorStateList stateList = mState.mTint;
+        if (mRipplePaint != null && mState.mColor != null) {
+            final ColorStateList stateList = mState.mColor;
             final int newColor = stateList.getColorForState(stateSet, 0);
             final int oldColor = mRipplePaint.getColor();
             if (oldColor != newColor) {
@@ -248,10 +267,8 @@
         return true;
     }
 
-    @Override
-    public void setTint(ColorStateList tint, Mode tintMode) {
-        mState.mTint = tint;
-        mState.setTintMode(tintMode);
+    public void setColor(ColorStateList color) {
+        mState.mColor = color;
         invalidateSelf();
     }
 
@@ -312,22 +329,15 @@
         // Extract the theme attributes, if any.
         state.mTouchThemeAttrs = a.extractThemeAttrs();
 
-        final ColorStateList tint = a.getColorStateList(R.styleable.RippleDrawable_tint);
-        if (tint != null) {
-            mState.mTint = tint;
+        final ColorStateList color = a.getColorStateList(R.styleable.RippleDrawable_color);
+        if (color != null) {
+            mState.mColor = color;
         }
 
-        final int tintMode = a.getInt(R.styleable.RippleDrawable_tintMode, -1);
-        if (tintMode != -1) {
-            mState.setTintMode(Drawable.parseTintMode(tintMode, Mode.SRC_ATOP));
-        }
-
-        mState.mPinned = a.getBoolean(R.styleable.RippleDrawable_pinned, mState.mPinned);
-
         // If we're not waiting on a theme, verify required attributes.
-        if (state.mTouchThemeAttrs == null && mState.mTint == null) {
+        if (state.mTouchThemeAttrs == null && mState.mColor == null) {
             throw new XmlPullParserException(a.getPositionDescription() +
-                    ": <ripple> requires a valid tint attribute");
+                    ": <ripple> requires a valid color attribute");
         }
     }
 
@@ -372,11 +382,6 @@
 
     @Override
     public void setHotspot(float x, float y) {
-        if (mState.mPinned && !circleContains(mHotspotBounds, x, y)) {
-            x = mHotspotBounds.exactCenterX();
-            y = mHotspotBounds.exactCenterY();
-        }
-
         if (mHotspot == null) {
             mHotspot = new Ripple(this, mHotspotBounds, x, y);
 
@@ -388,18 +393,6 @@
         }
     }
 
-    private boolean circleContains(Rect bounds, float x, float y) {
-        final float pX = bounds.exactCenterX() - x;
-        final float pY = bounds.exactCenterY() - y;
-        final double pointRadius = Math.sqrt(pX * pX + pY * pY);
-
-        final float bX = bounds.width() / 2.0f;
-        final float bY = bounds.height() / 2.0f;
-        final double boundsRadius = Math.sqrt(bX * bX + bY * bY);
-
-        return pointRadius < boundsRadius;
-    }
-
     /**
      * Creates an active hotspot at the specified location.
      */
@@ -417,7 +410,7 @@
             mHotspot = new Ripple(this, mHotspotBounds, x, y);
         }
 
-        final int color = mState.mTint.getColorForState(getState(), Color.TRANSPARENT);
+        final int color = mState.mColor.getColorForState(getState(), Color.TRANSPARENT);
         mHotspot.setup(mState.mMaxRadius, color, mDensity);
         mHotspot.enter();
 
@@ -485,8 +478,10 @@
         final int contentLayer = drawNonMaskContent ?
                 drawContentLayer(canvas, bounds, SRC_OVER) : -1;
 
-        // Next, try to draw the ripples (into a layer if necessary).
-        final int rippleLayer = drawRippleLayer(canvas, bounds, mState.mTintXfermode);
+        // Next, try to draw the ripples (into a layer if necessary). If we need
+        // to mask against the underlying content, set the xfermode to SRC_ATOP.
+        final PorterDuffXfermode xfermode = (hasMask || !drawNonMaskContent) ? SRC_OVER : SRC_ATOP;
+        final int rippleLayer = drawRippleLayer(canvas, bounds, xfermode);
 
         // If we have ripples and a non-opaque mask, draw the masking layer.
         if (rippleLayer >= 0 && drawMask) {
@@ -533,14 +528,27 @@
     }
 
     private int drawContentLayer(Canvas canvas, Rect bounds, PorterDuffXfermode mode) {
-        // TODO: We don't need a layer if all the content is opaque.
-        final Paint maskingPaint = getMaskingPaint(mode);
-        final int restoreToCount = canvas.saveLayer(bounds.left, bounds.top,
-                bounds.right, bounds.bottom, maskingPaint);
-
-        // Draw everything except the mask.
         final ChildDrawable[] array = mLayerState.mChildren;
         final int count = mLayerState.mNum;
+
+        // We don't need a layer if we don't expect to draw any ripples, we have
+        // an explicit mask, or if the non-mask content is all opaque.
+        boolean needsLayer = false;
+        if (mAnimatingRipplesCount > 0 && mMask == null) {
+            for (int i = 0; i < count; i++) {
+                if (array[i].mId != R.id.mask
+                        && array[i].mDrawable.getOpacity() != PixelFormat.OPAQUE) {
+                    needsLayer = true;
+                    break;
+                }
+            }
+        }
+
+        final Paint maskingPaint = getMaskingPaint(mode);
+        final int restoreToCount = needsLayer ? canvas.saveLayer(bounds.left, bounds.top,
+                bounds.right, bounds.bottom, maskingPaint) : -1;
+
+        // Draw everything except the mask.
         for (int i = 0; i < count; i++) {
             if (array[i].mId != R.id.mask) {
                 array[i].mDrawable.draw(canvas);
@@ -559,8 +567,8 @@
         // Separate the ripple color and alpha channel. The alpha will be
         // applied when we merge the ripples down to the canvas.
         final int rippleARGB;
-        if (mState.mTint != null) {
-            rippleARGB = mState.mTint.getColorForState(getState(), Color.TRANSPARENT);
+        if (mState.mColor != null) {
+            rippleARGB = mState.mColor.getColorForState(getState(), Color.TRANSPARENT);
         } else {
             rippleARGB = Color.TRANSPARENT;
         }
@@ -665,31 +673,19 @@
 
     static class RippleState extends LayerState {
         int[] mTouchThemeAttrs;
-        ColorStateList mTint = null;
-        PorterDuffXfermode mTintXfermode = SRC_ATOP;
+        ColorStateList mColor = null;
         int mMaxRadius = RADIUS_AUTO;
-        boolean mPinned = false;
 
         public RippleState(RippleState orig, RippleDrawable owner, Resources res) {
             super(orig, owner, res);
 
             if (orig != null) {
                 mTouchThemeAttrs = orig.mTouchThemeAttrs;
-                mTint = orig.mTint;
-                mTintXfermode = orig.mTintXfermode;
+                mColor = orig.mColor;
                 mMaxRadius = orig.mMaxRadius;
-                mPinned = orig.mPinned;
             }
         }
 
-        public void setTintMode(Mode mode) {
-            mTintXfermode = new PorterDuffXfermode(mode);
-        }
-
-        public PorterDuffXfermode getTintXfermode() {
-            return mTintXfermode;
-        }
-
         @Override
         public boolean canApplyTheme() {
             return mTouchThemeAttrs != null || super.canApplyTheme();
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index c9921ba3..a58e3e7c 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -975,11 +975,14 @@
 // Bezier approximation
 ///////////////////////////////////////////////////////////////////////////////
 
+// Depth at which recursion is aborted
+#define ABORT_DEPTH 10
+
 void PathTessellator::recursiveCubicBezierVertices(
         float p1x, float p1y, float c1x, float c1y,
         float p2x, float p2y, float c2x, float c2y,
         float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-        Vector<Vertex>& outputVertices) {
+        Vector<Vertex>& outputVertices, int depth) {
     float dx = p2x - p1x;
     float dy = p2y - p1y;
     float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx);
@@ -988,7 +991,7 @@
 
     // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors
 
-    if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+    if (depth >= ABORT_DEPTH || d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
         pushToVector(outputVertices, p2x, p2y);
     } else {
@@ -1012,11 +1015,11 @@
         recursiveCubicBezierVertices(
                 p1x, p1y, p1c1x, p1c1y,
                 mx, my, p1c1c2x, p1c1c2y,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
         recursiveCubicBezierVertices(
                 mx, my, p2c1c2x, p2c1c2y,
                 p2x, p2y, p2c2x, p2c2y,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
     }
 }
 
@@ -1025,12 +1028,12 @@
         float bx, float by,
         float cx, float cy,
         float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-        Vector<Vertex>& outputVertices) {
+        Vector<Vertex>& outputVertices, int depth) {
     float dx = bx - ax;
     float dy = by - ay;
     float d = (cx - bx) * dy - (cy - by) * dx;
 
-    if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+    if (depth >= ABORT_DEPTH || d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
         pushToVector(outputVertices, bx, by);
     } else {
@@ -1044,9 +1047,9 @@
         float my = (acy + bcy) * 0.5f;
 
         recursiveQuadraticBezierVertices(ax, ay, mx, my, acx, acy,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
         recursiveQuadraticBezierVertices(mx, my, bx, by, bcx, bcy,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
     }
 }
 
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index f033470..8ac9a3b 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -105,7 +105,7 @@
             float bx, float by,
             float cx, float cy,
             float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-            Vector<Vertex> &outputVertices);
+            Vector<Vertex> &outputVertices, int depth = 0);
 
 /*
   endpoints p1, p2
@@ -117,7 +117,7 @@
             float p2x, float p2y,
             float c2x, float c2y,
             float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-            Vector<Vertex> &outputVertices);
+            Vector<Vertex> &outputVertices, int depth = 0);
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 41cc9d2..37d5347 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -39,6 +39,7 @@
 
 TessellationCache::Description::Description()
         : type(kNone)
+        , aa(false)
         , cap(SkPaint::kDefault_Cap)
         , style(SkPaint::kFill_Style)
         , strokeWidth(1.0f) {
@@ -47,6 +48,7 @@
 
 TessellationCache::Description::Description(Type type)
         : type(type)
+        , aa(false)
         , cap(SkPaint::kDefault_Cap)
         , style(SkPaint::kFill_Style)
         , strokeWidth(1.0f) {
@@ -55,6 +57,7 @@
 
 TessellationCache::Description::Description(Type type, const SkPaint* paint)
         : type(type)
+        , aa(paint->isAntiAlias())
         , cap(paint->getStrokeCap())
         , style(paint->getStyle())
         , strokeWidth(paint->getStrokeWidth()) {
@@ -63,6 +66,7 @@
 
 hash_t TessellationCache::Description::hash() const {
     uint32_t hash = JenkinsHashMix(0, type);
+    hash = JenkinsHashMix(hash, aa);
     hash = JenkinsHashMix(hash, cap);
     hash = JenkinsHashMix(hash, style);
     hash = JenkinsHashMix(hash, android::hash_type(strokeWidth));
@@ -165,12 +169,12 @@
     ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
             const SkPath* casterPerimeter, const Matrix4* transformXY, const Matrix4* transformZ,
             const Vector3& lightCenter, float lightRadius)
-        : drawTransform(drawTransform)
+        : drawTransform(*drawTransform)
         , localClip(localClip)
         , opaque(opaque)
-        , casterPerimeter(casterPerimeter)
-        , transformXY(transformXY)
-        , transformZ(transformZ)
+        , casterPerimeter(*casterPerimeter)
+        , transformXY(*transformXY)
+        , transformZ(*transformZ)
         , lightCenter(lightCenter)
         , lightRadius(lightRadius) {
     }
@@ -182,14 +186,19 @@
         delete bufferPair;
     }
 
-    // Note - only the localClip is deep copied, since other pointers point at Allocator controlled
-    // objects, which are safe for the entire frame
-    const Matrix4* drawTransform;
+    /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
+     * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
+     * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
+     *
+     * These deep copies could be avoided, long term, by cancelling or flushing outstanding tasks
+     * before tearning down single-frame LinearAllocators.
+     */
+    const Matrix4 drawTransform;
     const Rect localClip;
     bool opaque;
-    const SkPath* casterPerimeter;
-    const Matrix4* transformXY;
-    const Matrix4* transformZ;
+    const SkPath casterPerimeter;
+    const Matrix4 transformXY;
+    const Matrix4 transformZ;
     const Vector3 lightCenter;
     const float lightRadius;
 };
@@ -281,8 +290,8 @@
 
         VertexBuffer* ambientBuffer = new VertexBuffer;
         VertexBuffer* spotBuffer = new VertexBuffer;
-        tessellateShadows(t->drawTransform, &t->localClip, t->opaque, t->casterPerimeter,
-                t->transformXY, t->transformZ, t->lightCenter, t->lightRadius,
+        tessellateShadows(&t->drawTransform, &t->localClip, t->opaque, &t->casterPerimeter,
+                &t->transformXY, &t->transformZ, t->lightCenter, t->lightRadius,
                 *ambientBuffer, *spotBuffer);
 
         t->setResult(new TessellationCache::vertexBuffer_pair_t(ambientBuffer, spotBuffer));
@@ -345,11 +354,12 @@
 
 
 void TessellationCache::trim() {
-    uint32_t size = getSize();
-    while (size > mMaxSize) {
-        size -= mCache.peekOldestValue()->getSize();
-        mCache.removeOldest();
-    }
+    // uint32_t size = getSize();
+    // while (size > mMaxSize) {
+    //     size -= mCache.peekOldestValue()->getSize();
+    //     mCache.removeOldest();
+    // }
+    mCache.clear(); // Workaround caching tessellation corruption
     mShadowCache.clear();
 }
 
diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h
index 8f37230..d4ff943 100644
--- a/libs/hwui/TessellationCache.h
+++ b/libs/hwui/TessellationCache.h
@@ -55,6 +55,7 @@
         };
 
         Type type;
+        bool aa;
         SkPaint::Cap cap;
         SkPaint::Style style;
         float strokeWidth;
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ce9fbb1..458139b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2344,19 +2344,24 @@
         if (rctlr == null) {
             return false;
         }
-        IAudioService service = getService();
-        final RemoteController.OnClientUpdateListener l = rctlr.getUpdateListener();
-        final ComponentName listenerComponent = new ComponentName(mContext, l.getClass());
-        try {
-            int[] artworkDimensions = rctlr.getArtworkSize();
-            boolean reg = service.registerRemoteController(rctlr.getRcDisplay(),
-                    artworkDimensions[0]/*w*/, artworkDimensions[1]/*h*/,
-                    listenerComponent);
-            rctlr.setIsRegistered(reg);
-            return reg;
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in registerRemoteController " + e);
-            return false;
+        if (USE_SESSIONS) {
+            rctlr.startListeningToSessions();
+            return true;
+        } else {
+            IAudioService service = getService();
+            final RemoteController.OnClientUpdateListener l = rctlr.getUpdateListener();
+            final ComponentName listenerComponent = new ComponentName(mContext, l.getClass());
+            try {
+                int[] artworkDimensions = rctlr.getArtworkSize();
+                boolean reg = service.registerRemoteController(rctlr.getRcDisplay(),
+                        artworkDimensions[0]/* w */, artworkDimensions[1]/* h */,
+                        listenerComponent);
+                rctlr.setIsRegistered(reg);
+                return reg;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in registerRemoteController " + e);
+                return false;
+            }
         }
     }
 
@@ -2369,12 +2374,16 @@
         if (rctlr == null) {
             return;
         }
-        IAudioService service = getService();
-        try {
-            service.unregisterRemoteControlDisplay(rctlr.getRcDisplay());
-            rctlr.setIsRegistered(false);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
+        if (USE_SESSIONS) {
+            rctlr.stopListeningToSessions();
+        } else {
+            IAudioService service = getService();
+            try {
+                service.unregisterRemoteControlDisplay(rctlr.getRcDisplay());
+                rctlr.setIsRegistered(false);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
+            }
         }
     }
 
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 37115850..76c7299 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -19,11 +19,17 @@
 import android.app.ActivityManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.media.IRemoteControlDisplay;
 import android.media.MediaMetadataEditor;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -34,6 +40,7 @@
 import android.view.KeyEvent;
 
 import java.lang.ref.WeakReference;
+import java.util.List;
 
 /**
  * The RemoteController class is used to control media playback, display and update media metadata
@@ -56,6 +63,7 @@
     private final static int TRANSPORT_UNKNOWN = 0;
     private final static String TAG = "RemoteController";
     private final static boolean DEBUG = false;
+    private final static boolean USE_SESSIONS = true;
     private final static Object mGenLock = new Object();
     private final static Object mInfoLock = new Object();
     private final RcDisplay mRcd;
@@ -64,6 +72,11 @@
     private final int mMaxBitmapDimension;
     private MetadataEditor mMetadataEditor;
 
+    private MediaSessionManager mSessionManager;
+    private MediaSessionManager.SessionListener mSessionListener
+            = new TopTransportSessionListener();
+    private MediaController.Callback mSessionCb = new MediaControllerCallback();
+
     /**
      * Synchronized on mGenLock
      */
@@ -79,6 +92,8 @@
     private int mArtworkWidth = -1;
     private int mArtworkHeight = -1;
     private boolean mEnabled = true;
+    // synchronized on mInfoLock, for USE_SESSION apis.
+    private MediaController mCurrentSession;
 
     /**
      * Class constructor.
@@ -123,6 +138,8 @@
         mContext = context;
         mRcd = new RcDisplay(this);
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mSessionManager = (MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
 
         if (ActivityManager.isLowRamDeviceStatic()) {
             mMaxBitmapDimension = MAX_BITMAP_DIMENSION;
@@ -194,8 +211,15 @@
      * @hide
      */
     public String getRemoteControlClientPackageName() {
-        return mClientPendingIntentCurrent != null ?
-                mClientPendingIntentCurrent.getCreatorPackage() : null;
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                return mCurrentSession != null ? mCurrentSession.getSessionInfo().getPackageName()
+                        : null;
+            }
+        } else {
+            return mClientPendingIntentCurrent != null ?
+                    mClientPendingIntentCurrent.getCreatorPackage() : null;
+        }
     }
 
     /**
@@ -215,22 +239,38 @@
      * @see OnClientUpdateListener#onClientPlaybackStateUpdate(int, long, long, float)
      */
     public long getEstimatedMediaPosition() {
-        if (mLastPlaybackInfo != null) {
-            if (!RemoteControlClient.playbackPositionShouldMove(mLastPlaybackInfo.mState)) {
-                return mLastPlaybackInfo.mCurrentPosMs;
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                if (mCurrentSession != null) {
+                    PlaybackState state = mCurrentSession.getPlaybackState();
+                    if (state != null) {
+                        return state.getPosition();
+                    }
+                }
             }
-
-            // Take the current position at the time of state change and estimate.
-            final long thenPos = mLastPlaybackInfo.mCurrentPosMs;
-            if (thenPos < 0) {
-                return -1;
+        } else {
+            final PlaybackInfo lastPlaybackInfo;
+            synchronized (mInfoLock) {
+                lastPlaybackInfo = mLastPlaybackInfo;
             }
+            if (lastPlaybackInfo != null) {
+                if (!RemoteControlClient.playbackPositionShouldMove(lastPlaybackInfo.mState)) {
+                    return lastPlaybackInfo.mCurrentPosMs;
+                }
 
-            final long now = SystemClock.elapsedRealtime();
-            final long then = mLastPlaybackInfo.mStateChangeTimeMs;
-            final long sinceThen = now - then;
-            final long scaledSinceThen = (long) (sinceThen * mLastPlaybackInfo.mSpeed);
-            return thenPos + scaledSinceThen;
+                // Take the current position at the time of state change and
+                // estimate.
+                final long thenPos = lastPlaybackInfo.mCurrentPosMs;
+                if (thenPos < 0) {
+                    return -1;
+                }
+
+                final long now = SystemClock.elapsedRealtime();
+                final long then = lastPlaybackInfo.mStateChangeTimeMs;
+                final long sinceThen = now - then;
+                final long scaledSinceThen = (long) (sinceThen * lastPlaybackInfo.mSpeed);
+                return thenPos + scaledSinceThen;
+            }
         }
         return -1;
     }
@@ -267,30 +307,40 @@
         if (!KeyEvent.isMediaKey(keyEvent.getKeyCode())) {
             throw new IllegalArgumentException("not a media key event");
         }
-        final PendingIntent pi;
-        synchronized(mInfoLock) {
-            if (!mIsRegistered) {
-                Log.e(TAG, "Cannot use sendMediaKeyEvent() from an unregistered RemoteController");
-                return false;
-            }
-            if (!mEnabled) {
-                Log.e(TAG, "Cannot use sendMediaKeyEvent() from a disabled RemoteController");
-                return false;
-            }
-            pi = mClientPendingIntentCurrent;
-        }
-        if (pi != null) {
-            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-            intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-            try {
-                pi.send(mContext, 0, intent);
-            } catch (CanceledException e) {
-                Log.e(TAG, "Error sending intent for media button down: ", e);
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                if (mCurrentSession != null) {
+                    return mCurrentSession.dispatchMediaButtonEvent(keyEvent);
+                }
                 return false;
             }
         } else {
-            Log.i(TAG, "No-op when sending key click, no receiver right now");
-            return false;
+            final PendingIntent pi;
+            synchronized (mInfoLock) {
+                if (!mIsRegistered) {
+                    Log.e(TAG,
+                            "Cannot use sendMediaKeyEvent() from an unregistered RemoteController");
+                    return false;
+                }
+                if (!mEnabled) {
+                    Log.e(TAG, "Cannot use sendMediaKeyEvent() from a disabled RemoteController");
+                    return false;
+                }
+                pi = mClientPendingIntentCurrent;
+            }
+            if (pi != null) {
+                Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+                intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+                try {
+                    pi.send(mContext, 0, intent);
+                } catch (CanceledException e) {
+                    Log.e(TAG, "Error sending intent for media button down: ", e);
+                    return false;
+                }
+            } else {
+                Log.i(TAG, "No-op when sending key click, no receiver right now");
+                return false;
+            }
         }
         return true;
     }
@@ -311,11 +361,19 @@
         if (timeMs < 0) {
             throw new IllegalArgumentException("illegal negative time value");
         }
-        final int genId;
-        synchronized (mGenLock) {
-            genId = mClientGenerationIdCurrent;
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.getTransportControls().seekTo(timeMs);
+                }
+            }
+        } else {
+            final int genId;
+            synchronized (mGenLock) {
+                genId = mClientGenerationIdCurrent;
+            }
+            mAudioManager.setRemoteControlClientPlaybackPosition(genId, timeMs);
         }
-        mAudioManager.setRemoteControlClientPlaybackPosition(genId, timeMs);
         return true;
     }
 
@@ -430,7 +488,6 @@
         return editor;
     }
 
-
     /**
      * A class to read the metadata published by a {@link RemoteControlClient}, or send a
      * {@link RemoteControlClient} new values for keys that can be edited.
@@ -477,26 +534,41 @@
             if (!mMetadataChanged) {
                 return;
             }
-            final int genId;
-            synchronized(mGenLock) {
-                genId = mClientGenerationIdCurrent;
-            }
-            synchronized(mInfoLock) {
-                if (mEditorMetadata.containsKey(
-                        String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
-                    Rating rating = (Rating) getObject(
-                            MediaMetadataEditor.RATING_KEY_BY_USER, null);
-                    mAudioManager.updateRemoteControlClientMetadata(genId,
-                          MediaMetadataEditor.RATING_KEY_BY_USER,
-                          rating);
-                } else {
-                    Log.e(TAG, "no metadata to apply");
+            if (USE_SESSIONS) {
+                synchronized (mInfoLock) {
+                    if (mCurrentSession != null) {
+                        if (mEditorMetadata.containsKey(
+                                String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
+                            Rating rating = (Rating) getObject(
+                                    MediaMetadataEditor.RATING_KEY_BY_USER, null);
+                            if (rating != null) {
+                                mCurrentSession.getTransportControls().setRating(rating);
+                            }
+                        }
+                    }
                 }
-                // NOT setting mApplied to true as this type of MetadataEditor will be applied
-                // multiple times, whenever the user of a RemoteController needs to change the
-                // metadata (e.g. user changes the rating of a song more than once during playback)
-                mApplied = false;
+            } else {
+                final int genId;
+                synchronized(mGenLock) {
+                    genId = mClientGenerationIdCurrent;
+                }
+                synchronized(mInfoLock) {
+                    if (mEditorMetadata.containsKey(
+                            String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
+                        Rating rating = (Rating) getObject(
+                                MediaMetadataEditor.RATING_KEY_BY_USER, null);
+                        mAudioManager.updateRemoteControlClientMetadata(genId,
+                              MediaMetadataEditor.RATING_KEY_BY_USER,
+                              rating);
+                    } else {
+                        Log.e(TAG, "no metadata to apply");
+                    }
+                }
             }
+            // NOT setting mApplied to true as this type of MetadataEditor will be applied
+            // multiple times, whenever the user of a RemoteController needs to change the
+            // metadata (e.g. user changes the rating of a song more than once during playback)
+            mApplied = false;
         }
 
     }
@@ -649,6 +721,46 @@
         }
     }
 
+    /**
+     * This receives updates when the current session changes. This is
+     * registered to receive the updates on the handler thread so it can call
+     * directly into the appropriate methods.
+     */
+    private class MediaControllerCallback extends MediaController.Callback {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            onNewPlaybackState(state);
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            onNewMediaMetadata(metadata);
+        }
+    }
+
+    /**
+     * Listens for changes to the active session stack and replaces the
+     * currently tracked session if it has changed.
+     */
+    private class TopTransportSessionListener extends MediaSessionManager.SessionListener {
+        @Override
+        public void onActiveSessionsChanged(List<MediaController> controllers) {
+            int size = controllers.size();
+            for (int i = 0; i < size; i++) {
+                MediaController controller = controllers.get(i);
+                long flags = controller.getFlags();
+                // We only care about sessions that handle transport controls,
+                // which will be true for apps using RCC
+                if ((flags & MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS) != 0) {
+                    updateController(controller);
+                    return;
+                }
+            }
+            updateController(null);
+        }
+
+    }
+
     //==================================================
     // Event handling
     private final EventHandler mEventHandler;
@@ -658,6 +770,8 @@
     private final static int MSG_NEW_METADATA       = 3; // msg always has non-null obj parameter
     private final static int MSG_CLIENT_CHANGE      = 4;
     private final static int MSG_DISPLAY_ENABLE     = 5;
+    private final static int MSG_NEW_PLAYBACK_STATE = 6;
+    private final static int MSG_NEW_MEDIA_METADATA = 7;
 
     private class EventHandler extends Handler {
 
@@ -686,12 +800,46 @@
                 case MSG_DISPLAY_ENABLE:
                     onDisplayEnable(msg.arg1 == 1);
                     break;
+                case MSG_NEW_PLAYBACK_STATE:
+                    // same as new playback info but using new apis
+                    onNewPlaybackState((PlaybackState) msg.obj);
+                    break;
+                case MSG_NEW_MEDIA_METADATA:
+                    onNewMediaMetadata((MediaMetadata) msg.obj);
+                    break;
                 default:
                     Log.e(TAG, "unknown event " + msg.what);
             }
         }
     }
 
+    /**
+     * @hide
+     */
+    void startListeningToSessions() {
+        final ComponentName listenerComponent = new ComponentName(mContext,
+                mOnClientUpdateListener.getClass());
+        mSessionManager.addActiveSessionsListener(mSessionListener, listenerComponent,
+                ActivityManager.getCurrentUser());
+        mSessionListener.onActiveSessionsChanged(mSessionManager
+                .getActiveSessions(listenerComponent));
+        if (DEBUG) {
+            Log.d(TAG, "Registered session listener with component " + listenerComponent
+                    + " for user " + ActivityManager.getCurrentUser());
+        }
+    }
+
+    /**
+     * @hide
+     */
+    void stopListeningToSessions() {
+        mSessionManager.removeActiveSessionsListener(mSessionListener);
+        if (DEBUG) {
+            Log.d(TAG, "Unregistered session listener for user "
+                    + ActivityManager.getCurrentUser());
+        }
+    }
+
     /** If the msg is already queued, replace it with this one. */
     private static final int SENDMSG_REPLACE = 0;
     /** If the msg is already queued, ignore this one and leave the old. */
@@ -713,6 +861,7 @@
         handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delayMs);
     }
 
+    ///////////// These calls are used by the old APIs with RCC and RCD //////////////////////
     private void onNewPendingIntent(int genId, PendingIntent pi) {
         synchronized(mGenLock) {
             if (mClientGenerationIdCurrent != genId) {
@@ -848,6 +997,86 @@
         }
     }
 
+    ///////////// These calls are used by the new APIs with Sessions //////////////////////
+    private void updateController(MediaController controller) {
+        if (DEBUG) {
+            Log.d(TAG, "Updating controller to " + controller + " previous controller is "
+                    + mCurrentSession);
+        }
+        synchronized (mInfoLock) {
+            if (controller == null) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.removeCallback(mSessionCb);
+                    mCurrentSession = null;
+                    sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+                            0 /* genId */, 1 /* clearing */, null /* obj */, 0 /* delay */);
+                }
+            } else if (mCurrentSession == null
+                    || !controller.getSessionInfo().getId()
+                            .equals(mCurrentSession.getSessionInfo().getId())) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.removeCallback(mSessionCb);
+                }
+                sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+                        0 /* genId */, 0 /* clearing */, null /* obj */, 0 /* delay */);
+                mCurrentSession = controller;
+                mCurrentSession.addCallback(mSessionCb, mEventHandler);
+
+                PlaybackState state = controller.getPlaybackState();
+                sendMsg(mEventHandler, MSG_NEW_PLAYBACK_STATE, SENDMSG_REPLACE,
+                        0 /* genId */, 0, state /* obj */, 0 /* delay */);
+
+                MediaMetadata metadata = controller.getMetadata();
+                sendMsg(mEventHandler, MSG_NEW_MEDIA_METADATA, SENDMSG_REPLACE,
+                        0 /* arg1 */, 0 /* arg2 */, metadata /* obj */, 0 /* delay */);
+            }
+            // else same controller, no need to update
+        }
+    }
+
+    private void onNewPlaybackState(PlaybackState state) {
+        final OnClientUpdateListener l;
+        synchronized (mInfoLock) {
+            l = this.mOnClientUpdateListener;
+        }
+        if (l != null) {
+            int playstate = state == null ? RemoteControlClient.PLAYSTATE_NONE : PlaybackState
+                    .getRccStateFromState(state.getState());
+            if (state == null || state.getPosition() == PlaybackState.PLAYBACK_POSITION_UNKNOWN) {
+                l.onClientPlaybackStateUpdate(playstate);
+            } else {
+                l.onClientPlaybackStateUpdate(playstate, state.getLastPositionUpdateTime(),
+                        state.getPosition(), state.getPlaybackRate());
+            }
+            if (state != null) {
+                l.onClientTransportControlUpdate(PlaybackState.getRccControlFlagsFromActions(state
+                        .getActions()));
+            }
+        }
+    }
+
+    private void onNewMediaMetadata(MediaMetadata metadata) {
+        if (metadata == null) {
+            // RemoteController only handles non-null metadata
+            return;
+        }
+        final OnClientUpdateListener l;
+        final MetadataEditor metadataEditor;
+        // prepare the received Bundle to be used inside a MetadataEditor
+        synchronized(mInfoLock) {
+            l = mOnClientUpdateListener;
+            boolean canRate = mCurrentSession != null
+                    && mCurrentSession.getRatingType() != Rating.RATING_NONE;
+            long editableKeys = canRate ? MediaMetadataEditor.RATING_KEY_BY_USER : 0;
+            Bundle legacyMetadata = MediaSessionLegacyHelper.getOldMetadata(metadata);
+            mMetadataEditor = new MetadataEditor(legacyMetadata, editableKeys);
+            metadataEditor = mMetadataEditor;
+        }
+        if (l != null) {
+            l.onClientMetadataUpdate(metadataEditor);
+        }
+    }
+
     //==================================================
     private static class PlaybackInfo {
         int mState;
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 7c03907..f0cd785 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -37,6 +37,7 @@
     boolean isTransportControlEnabled();
     void showRoutePicker();
     MediaSessionInfo getSessionInfo();
+    long getFlags();
 
     // These commands are for the TransportController
     void play();
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 57a0a54..5ca7daa 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -57,6 +57,7 @@
     private final Object mLock = new Object();
 
     private boolean mCbRegistered = false;
+    private MediaSessionInfo mInfo;
 
     private TransportControls mTransportController;
 
@@ -174,6 +175,21 @@
     }
 
     /**
+     * Get the flags for this session.
+     *
+     * @return The current set of flags for the session.
+     * @hide
+     */
+    public long getFlags() {
+        try {
+            return mSessionBinder.getFlags();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getFlags.", e);
+        }
+        return 0;
+    }
+
+    /**
      * Adds a callback to receive updates from the Session. Updates will be
      * posted on the caller's thread.
      *
@@ -253,12 +269,14 @@
      * @hide
      */
     public MediaSessionInfo getSessionInfo() {
-        try {
-            return mSessionBinder.getSessionInfo();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error in getSessionInfo.", e);
+        if (mInfo == null) {
+            try {
+                mInfo = mSessionBinder.getSessionInfo();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error in getSessionInfo.", e);
+            }
         }
-        return null;
+        return mInfo;
     }
 
     /*
diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java
index 099f601..801844f 100644
--- a/media/java/android/media/session/MediaSessionLegacyHelper.java
+++ b/media/java/android/media/session/MediaSessionLegacyHelper.java
@@ -20,6 +20,10 @@
 import android.app.PendingIntent.CanceledException;
 import android.content.Context;
 import android.content.Intent;
+import android.media.MediaMetadata;
+import android.media.MediaMetadataEditor;
+import android.media.MediaMetadataRetriever;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.ArrayMap;
@@ -64,6 +68,88 @@
         return sInstance;
     }
 
+    public static Bundle getOldMetadata(MediaMetadata metadata) {
+        Bundle oldMetadata = new Bundle();
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUM),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ALBUM));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ART)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+                    metadata.getBitmap(MediaMetadata.METADATA_KEY_ART));
+        } else if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)) {
+            // Fall back to album art if the track art wasn't available
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+                    metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ARTIST)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ARTIST));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_AUTHOR)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_AUTHOR),
+                    metadata.getString(MediaMetadata.METADATA_KEY_AUTHOR));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPILATION)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPILATION),
+                    metadata.getString(MediaMetadata.METADATA_KEY_COMPILATION));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPOSER)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPOSER),
+                    metadata.getString(MediaMetadata.METADATA_KEY_COMPOSER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DATE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DATE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_DATE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DISC_NUMBER)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_DISC_NUMBER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_DURATION));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_GENRE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_GENRE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_GENRE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_NUM_TRACKS)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_RATING)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_OTHERS),
+                    metadata.getRating(MediaMetadata.METADATA_KEY_RATING));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_USER_RATING)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER),
+                    metadata.getRating(MediaMetadata.METADATA_KEY_USER_RATING));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER)) {
+            oldMetadata.putLong(
+                    String.valueOf(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_WRITER)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_WRITER),
+                    metadata.getString(MediaMetadata.METADATA_KEY_WRITER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_YEAR)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_YEAR),
+                    metadata.getString(MediaMetadata.METADATA_KEY_YEAR));
+        }
+        return oldMetadata;
+    }
+
     public MediaSession getSession(PendingIntent pi) {
         SessionHolder holder = mSessions.get(pi);
         return holder == null ? null : holder.mSession;
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 291bfc8..2e6b86e 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -96,10 +96,13 @@
     }
 
     /**
-     * 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. You may also retrieve this list if your app is an
-     * enabled notification listener using the
+     * Get a list of controllers for all ongoing sessions. The controllers will
+     * be provided in priority order with the most important controller at index
+     * 0.
+     * <p>
+     * This requires the android.Manifest.permission.MEDIA_CONTENT_CONTROL
+     * permission be held by the calling app. You may also retrieve this list if
+     * your app is an enabled notification listener using the
      * {@link NotificationListenerService} APIs, in which case you must pass the
      * {@link ComponentName} of your enabled listener.
      *
@@ -130,7 +133,8 @@
         ArrayList<MediaController> controllers = new ArrayList<MediaController>();
         try {
             List<IBinder> binders = mService.getSessions(notificationListener, userId);
-            for (int i = binders.size() - 1; i >= 0; i--) {
+            int size = binders.size();
+            for (int i = 0; i < size; i++) {
                 MediaController controller = MediaController.fromBinder(ISessionController.Stub
                         .asInterface(binders.get(i)));
                 controllers.add(controller);
@@ -239,7 +243,8 @@
         /**
          * Called when the list of active sessions has changed. This can be due
          * to a session being added or removed or the order of sessions
-         * changing.
+         * changing. The controllers will be provided in priority order with the
+         * most important controller at index 0.
          *
          * @param controllers The updated list of controllers for the user that
          *            changed.
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index e09ac3f..3b3f249 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -432,6 +432,8 @@
                 return STATE_REWINDING;
             case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
                 return STATE_SKIPPING_TO_PREVIOUS;
+            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+                return STATE_SKIPPING_TO_NEXT;
             case RemoteControlClient.PLAYSTATE_STOPPED:
                 return STATE_STOPPED;
             default:
@@ -440,6 +442,41 @@
     }
 
     /**
+     * Get the {@link RemoteControlClient} state for the given
+     * {@link PlaybackState} state.
+     *
+     * @param state The state used by {@link PlaybackState}.
+     * @return The equivalent state used by {@link RemoteControlClient}.
+     * @hide
+     */
+    public static int getRccStateFromState(int state) {
+        switch (state) {
+            case STATE_BUFFERING:
+                return RemoteControlClient.PLAYSTATE_BUFFERING;
+            case STATE_ERROR:
+                return RemoteControlClient.PLAYSTATE_ERROR;
+            case STATE_FAST_FORWARDING:
+                return RemoteControlClient.PLAYSTATE_FAST_FORWARDING;
+            case STATE_NONE:
+                return RemoteControlClient.PLAYSTATE_NONE;
+            case STATE_PAUSED:
+                return RemoteControlClient.PLAYSTATE_PAUSED;
+            case STATE_PLAYING:
+                return RemoteControlClient.PLAYSTATE_PLAYING;
+            case STATE_REWINDING:
+                return RemoteControlClient.PLAYSTATE_REWINDING;
+            case STATE_SKIPPING_TO_PREVIOUS:
+                return RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS;
+            case STATE_SKIPPING_TO_NEXT:
+                return RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS;
+            case STATE_STOPPED:
+                return RemoteControlClient.PLAYSTATE_STOPPED;
+            default:
+                return -1;
+        }
+    }
+
+    /**
      * @hide
      */
     public static long getActionsFromRccControlFlags(int rccFlags) {
@@ -454,6 +491,21 @@
         return actions;
     }
 
+    /**
+     * @hide
+     */
+    public static int getRccControlFlagsFromActions(long actions) {
+        int rccFlags = 0;
+        long action = 1;
+        while (action <= actions && action < Integer.MAX_VALUE) {
+            if ((action & actions) != 0) {
+                rccFlags |= getRccFlagForAction(action);
+            }
+            action = action << 1;
+        }
+        return rccFlags;
+    }
+
     private static long getActionForRccFlag(int flag) {
         switch (flag) {
             case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS:
@@ -480,6 +532,35 @@
         return 0;
     }
 
+    private static int getRccFlagForAction(long action) {
+        // We only care about the lower set of actions that can map to rcc
+        // flags.
+        int testAction = action < Integer.MAX_VALUE ? (int) action : 0;
+        switch (testAction) {
+            case (int) ACTION_SKIP_TO_PREVIOUS:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS;
+            case (int) ACTION_REWIND:
+                return RemoteControlClient.FLAG_KEY_MEDIA_REWIND;
+            case (int) ACTION_PLAY:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY;
+            case (int) ACTION_PLAY_PAUSE:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE;
+            case (int) ACTION_PAUSE:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PAUSE;
+            case (int) ACTION_STOP:
+                return RemoteControlClient.FLAG_KEY_MEDIA_STOP;
+            case (int) ACTION_FAST_FORWARD:
+                return RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD;
+            case (int) ACTION_SKIP_TO_NEXT:
+                return RemoteControlClient.FLAG_KEY_MEDIA_NEXT;
+            case (int) ACTION_SEEK_TO:
+                return RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE;
+            case (int) ACTION_SET_RATING:
+                return RemoteControlClient.FLAG_KEY_MEDIA_RATING;
+        }
+        return 0;
+    }
+
     public static final Parcelable.Creator<PlaybackState> CREATOR
             = new Parcelable.Creator<PlaybackState>() {
         @Override
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index 2917faa..006b1ee 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -56,7 +56,7 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/date_owner_info_margin"
             android:layout_gravity="center_horizontal"
-            android:textColor="#99ffffff"
+            android:textColor="#ccffffff"
             android:textSize="@dimen/widget_label_font_size"
             android:ellipsize="marquee"
             android:singleLine="true" />
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
index d23d487..f258224 100644
--- a/packages/Keyguard/res/values-ca/strings.xml
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -59,7 +59,7 @@
     <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"S\'ha iniciat la reorganització del widget."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ha finalitzat la reorganització del widget."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"S\'ha suprimit el widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
-    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Amplia l\'àrea de desbloqueig."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Desplega l\'àrea de desbloqueig."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant el dit"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueig mitjançant patró"</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueig facial"</string>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
index 200b42e..f197138 100644
--- a/packages/Keyguard/res/values-hi/strings.xml
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -31,7 +31,7 @@
     <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत पिन कोड."</string>
     <string name="keyguard_label_text" msgid="861796461028298424">"अनलॉक करने के लिए, मेनू दबाएं और फिर 0 दबाएं."</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"फेस अनलॉक के अधिकतम प्रयासों की सीमा पार हो गई"</string>
-    <string name="keyguard_charged" msgid="3272223906073492454">"चार्ज हो गई"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"चार्ज हो गई है"</string>
     <string name="keyguard_plugged_in" msgid="9087497435553252863">"चार्ज हो रहा है"</string>
     <string name="keyguard_low_battery" msgid="8143808018719173859">"अपना चार्जर कनेक्‍ट करें."</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलॉक करने के लिए मेनू दबाएं."</string>
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
index c26b1b4..ecdad8c 100644
--- a/packages/Keyguard/res/values-km-rKH/strings.xml
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -83,7 +83,7 @@
     <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>
@@ -120,7 +120,7 @@
     <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_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>
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
index e9e9b89..69bf44f 100644
--- a/packages/Keyguard/res/values-sw600dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -63,14 +63,11 @@
     <dimen name="keyguard_muliuser_selector_margin">12dp</dimen>
 
     <!-- Overload default clock widget parameters -->
-    <dimen name="widget_big_font_size">96dp</dimen>
+    <dimen name="widget_big_font_size">120dp</dimen>
     <dimen name="widget_label_font_size">16sp</dimen>
-    <dimen name="bottom_text_spacing_digital">-8dp</dimen>
+    <dimen name="bottom_text_spacing_digital">-16dp</dimen>
 
     <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
          Should be 0 on devices with plenty of room (e.g. tablets) -->
     <dimen name="eca_overlap">0dip</dimen>
-
-    <!-- The vertical margin between the date and the owner info. -->
-    <dimen name="date_owner_info_margin">4dp</dimen>
 </resources>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index f971522..4b113ff 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -155,15 +155,15 @@
     <dimen name="eca_overlap">-10dip</dimen>
 
     <!-- Default clock parameters -->
-    <dimen name="bottom_text_spacing_digital">-6dp</dimen>
+    <dimen name="bottom_text_spacing_digital">-10dp</dimen>
     <dimen name="label_font_size">14dp</dimen>
-    <dimen name="widget_label_font_size">14sp</dimen>
-    <dimen name="widget_big_font_size">68dp</dimen>
+    <dimen name="widget_label_font_size">16sp</dimen>
+    <dimen name="widget_big_font_size">96dp</dimen>
     <dimen name="big_font_size">120dp</dimen>
 
     <!-- The y translation to apply at the start in appear animations. -->
     <dimen name="appear_y_translation_start">32dp</dimen>
 
     <!-- The vertical margin between the date and the owner info. -->
-    <dimen name="date_owner_info_margin">2dp</dimen>
+    <dimen name="date_owner_info_margin">10dp</dimen>
 </resources>
diff --git a/packages/Keyguard/res/values/donottranslate.xml b/packages/Keyguard/res/values/donottranslate.xml
index 16f5a3e..78636db 100644
--- a/packages/Keyguard/res/values/donottranslate.xml
+++ b/packages/Keyguard/res/values/donottranslate.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Skeleton string format for displaying the date. -->
-    <string name="abbrev_wday_month_day_no_year">EEEMMMMd</string>
+    <string name="abbrev_wday_month_day_no_year">EEEEMMMMd</string>
 
     <!-- Skeleton string format for displaying the time in 12-hour format. -->
     <string name="clock_12hr_format">hm</string>
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
deleted file mode 100644
index e6af81e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 873ca7e..b28624f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
index 9d3cf53..9ce434d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index 288d36a..51dce69 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
index 266d34d..3f3e288 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
index 0298054..9856cbf 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
index 91e2edf..6910456 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
index 9ed15a7..e8c6ec6 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
index 6f2915b..06dcd20 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
index 3f3b692..240f536 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_lower_gradient.9.png b/packages/SystemUI/res/drawable-hdpi/recents_lower_gradient.9.png
new file mode 100644
index 0000000..d4fdbf3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recents_lower_gradient.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png
deleted file mode 100644
index 6cd1176..0000000
--- a/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
deleted file mode 100644
index 5ce8708..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
index 3f7c4b0..e464347 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
index 956bb7c..f8b59e8 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 86e2947..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d8ab8ea..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
index a53aef1..1b578a6 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
index e1b2145..80ecaba 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index dffc059..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index c0209b0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
index 2d8f81d..c7bf2c7 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
index 61c6d11..278de42 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index a67ed6d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 6101333..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
index 90eece6..464831c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
index 382cf23..c24132c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index ca1c8c4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index cfef88d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
index a4b3b37..bc84f22 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
index ee5f623..f4e219e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index ca3c541..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 78d4490..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
index 3d21350..ece2e37 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
index 40fbaec..d524dcf 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 77bef31..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d79f5b7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
index 61b4569..373e84a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
index 1a0312b..e5a102a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index d04916e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d940d34..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
index 8715a11..6b19593 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
index 487a0b1..a5e0686 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index a7cff47..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 0a60bb6..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
deleted file mode 100644
index e865f4c..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index 225d924..f878093 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
index 7779d57..7780b16 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
index 37d17d2..343d0dd 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
index 5e70a07..8e9583b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
index 39a0c07..7d38703 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
index 5bbf3fe..6e186a3 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
index 798f62f..12b4042 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
index f8e549a..e2a89c3 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
index c7fda96..311720b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_lower_gradient.9.png b/packages/SystemUI/res/drawable-mdpi/recents_lower_gradient.9.png
new file mode 100644
index 0000000..9fc1a3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/recents_lower_gradient.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png
deleted file mode 100644
index 7237f09..0000000
--- a/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
deleted file mode 100644
index bdf0f67..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
index 3361e34..67e4ee7 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
index ed52bc3..dfef430 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
index b380327..de6d109 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
index 49df31b..7d0c3fbe 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
index ac45bcd..3baeb52 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
index 9fb4266..d5b48e8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
index 459d011..26d7e7b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
index e1cddde..c49198d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
index e459f2c..2a21f29 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
index 0ec4d23..538d7d1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
index 4dedcbe..eb8e80b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
index e55f2bf..1c2c35a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
index a39c3e5..eec613f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
index 80e988f..1c0bad8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
index 4ef12b0d..1293fa8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
index 8ef12a8..96a9cce 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
index c2977c0..9ffc80a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
index 60ec10e..aa9b57b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
index 8aa6e3a..b343522 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
index e272b62..f2f7b50 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
index bf68b22..383398c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
index 59ef663..53444ab 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
index cf3a5ff..4294937 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
index 2598954..7cb3ee4 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
index 66853db..b017946 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
index c46fd026..e8dd07c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
index 0e84d92..f396ea9 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
index 7e96395e..1b817cf 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
index cb94580..21b7a06 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
index 382ef39..676fc14 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
index 8d7be53..26f4ba9 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
index 613fba0a..ea21b60 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
index 0511ad1..c7d77c2 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
index 77fe9b2..ae12cfd 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
index ae78eb0..8c27d45 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
index 5b446b1a..c98827c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
deleted file mode 100644
index 83693c1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index a2bb50a..ec2951d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
index 24897ce..5103190 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index aaeeb1b..818aa4f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
index ddee461..254f757 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
index 23a7997..f0de417 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
index 9f200c2..97f1526 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
index 43e9bc2..773fa94 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
index 5c0ba82..8a8e941 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
index b76a0ca..ad7dfc3 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_lower_gradient.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_lower_gradient.9.png
new file mode 100644
index 0000000..f38de93
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_lower_gradient.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png
deleted file mode 100644
index 8d56a1d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
deleted file mode 100644
index 461535c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
deleted file mode 100644
index cebbb15..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
index 79cfcee..77969b8 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
index 7959f65..b171f92 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
index c3bfcfb..ad35c65 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
index 64f6a22..d60229f 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
index 8fd36bc..8fffa8e 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
index 6f30e54..9215055 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
index 024ef8f..bcf7eb1 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
index 6e0b071..a261f85 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
index 9a56987..4c612f7 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_lower_gradient.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_lower_gradient.9.png
new file mode 100644
index 0000000..8194605
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/recents_lower_gradient.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png
deleted file mode 100644
index aed300b..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
deleted file mode 100644
index 7b03a11..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_notify_zen.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/ic_qs_location_01.xml
copy to packages/SystemUI/res/drawable/ic_notify_zen.xml
index ff37d9a..c46455b 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_zen.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="24dp"
+        android:height="24dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+        android:pathData="M4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0s20.0,-9.0 20.0,-20.0S35.0,4.0 24.0,4.0S4.0,13.0 4.0,24.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8zM8.0,24.0c0.0,-3.7 1.3,-7.1 3.4,-9.8L33.8,36.6C31.1,38.7 27.7,40.0 24.0,40.0C15.2,40.0 8.0,32.8 8.0,24.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_power_low.xml
similarity index 66%
copy from packages/SystemUI/res/drawable/ic_qs_location_01.xml
copy to packages/SystemUI/res/drawable/ic_power_low.xml
index ff37d9a..5bb7aba 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_power_low.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="24.0dp"
+        android:height="24.0dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+        android:pathData="M30.0,6.0L30.0,2.0L18.0,2.0l0.0,4.0l-8.0,0.0l0.0,40.0l28.0,0.0L38.0,6.0L30.0,6.0zM26.0,37.0l-4.0,0.0l0.0,-4.0l4.0,0.0L26.0,37.0zM26.0,30.0l-4.0,0.0L22.0,15.0l4.0,0.0L26.0,30.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_power_saver.xml
similarity index 66%
copy from packages/SystemUI/res/drawable/ic_qs_location_01.xml
copy to packages/SystemUI/res/drawable/ic_power_saver.xml
index ff37d9a..26e7375d 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_power_saver.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="24.0dp"
+        android:height="24.0dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+        android:pathData="M30.0,6.0L30.0,2.0L18.0,2.0l0.0,4.0l-8.0,0.0l0.0,40.0l28.0,0.0L38.0,6.0L30.0,6.0zM32.0,28.0l-6.0,0.0l0.0,6.0l-4.0,0.0l0.0,-6.0l-6.0,0.0l0.0,-4.0l6.0,0.0l0.0,-6.0l4.0,0.0l0.0,6.0l6.0,0.0L32.0,28.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml b/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml
deleted file mode 100644
index dc30a53..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M18.939,7.244c-5.887,-5.885 -6.214,-6.214 -6.222,-6.222l-0.707,-0.737L5.088,7.207c-2.914,2.915 -3.74,6.629 -2.266,10.19c1.541,3.719 5.312,6.316 9.174,6.317l0.0,0.0c3.861,-0.001 7.636,-2.603 9.179,-6.328C22.646,13.834 21.832,10.138 18.939,7.244zM4.67,16.632c-1.149,-2.776 -0.481,-5.696 1.832,-8.011l5.494,-5.492c0.0,0.002 0.002,0.003 0.003,0.004l0.0,18.582c-0.001,0.0 -0.002,0.0 -0.003,0.0C8.922,21.714 5.91,19.624 4.67,16.632z"/>
-</vector>
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..b6a5cad
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="64dp"
+        android:height="64dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#4DFFFFFF"
+        android:pathData="M41.3,41.7L36.6,37.0L24.0,24.5l-7.1,-7.1L14.0,14.5L8.5,9.0L6.0,11.5l5.6,5.6c-5.1,6.3 -4.7,15.5 1.1,21.4c3.1,3.1 7.2,4.7 11.3,4.7c3.6,0.0 7.1,-1.2 10.1,-3.6l5.4,5.4l2.5,-2.5L41.3,41.7zM24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5c0.0,-2.6 0.9,-5.1 2.4,-7.2l9.6,9.6L24.0,39.2zM24.0,10.2l0.0,9.2l14.5,14.5c2.7,-5.9 1.7,-13.1 -3.2,-18.0L24.0,4.5l0.0,0.0l0.0,0.0L16.6,12.0l2.8,2.8L24.0,10.2z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
similarity index 68%
rename from packages/SystemUI/res/drawable/ic_qs_location_01.xml
rename to packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
index ff37d9a..e8d59e0 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
@@ -19,10 +19,10 @@
         android:height="64dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+        android:pathData="M35.3,15.9L24.0,4.5l0.0,0.0l0.0,0.0L12.7,15.9c-6.2,6.2 -6.2,16.4 0.0,22.6c3.1,3.1 7.2,4.7 11.3,4.7s8.2,-1.6 11.3,-4.7C41.6,32.2 41.6,22.1 35.3,15.9zM24.0,39.2L24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5s1.2,-6.2 3.5,-8.5l8.5,-8.5L24.0,39.2z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_02.xml b/packages/SystemUI/res/drawable/ic_qs_location_02.xml
deleted file mode 100644
index bb4465f..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_02.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,4.0c-3.48,0.0 -6.3,2.82 -6.3,6.3C5.7,15.02 12.0,22.0 12.0,22.0s6.3,-6.98 6.3,-11.7C18.3,6.82 15.48,4.0 12.0,4.0zM12.0,12.55c-1.24,0.0 -2.25,-1.01 -2.25,-2.25S10.76,8.05 12.0,8.05c1.24,0.0 2.25,1.01 2.25,2.25S13.24,12.55 12.0,12.55z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_03.xml b/packages/SystemUI/res/drawable/ic_qs_location_03.xml
deleted file mode 100644
index 956a8c3..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_03.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,7.0c-2.9,0.0 -5.25,2.35 -5.25,5.25C6.75,16.19 12.0,22.0 12.0,22.0s5.25,-5.81 5.25,-9.75C17.25,9.35 14.9,7.0 12.0,7.0zM12.0,14.12c-1.04,0.0 -1.88,-0.84 -1.88,-1.88s0.84,-1.88 1.88,-1.88c1.04,0.0 1.87,0.84 1.87,1.88S13.04,14.12 12.0,14.12z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_04.xml b/packages/SystemUI/res/drawable/ic_qs_location_04.xml
deleted file mode 100644
index 0c0fb3b..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_04.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,10.0c-2.32,0.0 -4.2,1.88 -4.2,4.2C7.8,17.35 12.0,22.0 12.0,22.0s4.2,-4.65 4.2,-7.8C16.2,11.88 14.32,10.0 12.0,10.0zM12.0,15.7c-0.83,0.0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5c0.83,0.0 1.5,0.67 1.5,1.5S12.83,15.7 12.0,15.7z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_05.xml b/packages/SystemUI/res/drawable/ic_qs_location_05.xml
deleted file mode 100644
index 1a21e2f..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_05.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,13.0c-1.74,0.0 -3.15,1.41 -3.15,3.15C8.85,18.51 12.0,22.0 12.0,22.0s3.15,-3.49 3.15,-5.85C15.15,14.41 13.74,13.0 12.0,13.0zM12.0,17.27c-0.62,0.0 -1.13,-0.5 -1.13,-1.12c0.0,-0.62 0.5,-1.12 1.13,-1.12c0.62,0.0 1.12,0.5 1.12,1.12C13.12,16.77 12.62,17.27 12.0,17.27z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_06.xml b/packages/SystemUI/res/drawable/ic_qs_location_06.xml
deleted file mode 100644
index 5642a8a2..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_06.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,16.0c-1.16,0.0 -2.1,0.94 -2.1,2.1C9.9,19.67 12.0,22.0 12.0,22.0s2.1,-2.33 2.1,-3.9C14.1,16.94 13.16,16.0 12.0,16.0zM12.0,18.85c-0.41,0.0 -0.75,-0.34 -0.75,-0.75s0.34,-0.75 0.75,-0.75c0.41,0.0 0.75,0.34 0.75,0.75S12.41,18.85 12.0,18.85z"/>
-    <path
-        android:pathData="M11.99,15c-1.35,0,-2.45,1.1,-2.45,2.45      c0,1.84,2.45,4.55,2.45,4.55s2.45,-2.71,2.45,-4.55C14.44,16.1,13.34,15,11.99,15z M11.99,18.33c-0.48,0,-0.88,-0.39,-0.88,-0.88      s0.39,-0.88,0.88,-0.88c0.48,0,0.87,0.39,0.87,0.88S12.47,18.33,11.99,18.33z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_07.xml b/packages/SystemUI/res/drawable/ic_qs_location_07.xml
deleted file mode 100644
index 1ad2ebc..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_07.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,9c-2.51,0,-4.55,2.04,-4.55,4.55       C7.45,16.96,12,22,12,22s4.55,-5.04,4.55,-8.45C16.55,11.04,14.51,9,12,9z M12,15.18c-0.9,0,-1.63,-0.73,-1.63,-1.62       s0.73,-1.62,1.63,-1.62c0.9,0,1.62,0.73,1.62,1.62S12.9,15.18,12,15.18z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_08.xml b/packages/SystemUI/res/drawable/ic_qs_location_08.xml
deleted file mode 100644
index 179bc66..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_08.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,6c-3.09,0,-5.6,2.51,-5.6,5.6       C6.4,15.8,12,22,12,22s5.6,-6.2,5.6,-10.4C17.6,8.51,15.09,6,12,6z M12,13.6c-1.1,0,-2,-0.9,-2,-2s0.9,-2,2,-2c1.1,0,2,0.9,2,2       S13.1,13.6,12,13.6z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_09.xml b/packages/SystemUI/res/drawable/ic_qs_location_09.xml
deleted file mode 100644
index 6169af5..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_09.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,4c-3.48,0,-6.3,2.82,-6.3,6.3       C5.7,15.02,12,22,12,22s6.3,-6.98,6.3,-11.7C18.3,6.82,15.48,4,12,4z M12,12.55c-1.24,0,-2.25,-1.01,-2.25,-2.25S10.76,8.05,12,8.05       c1.24,0,2.25,1.01,2.25,2.25S13.24,12.55,12,12.55z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_10.xml b/packages/SystemUI/res/drawable/ic_qs_location_10.xml
deleted file mode 100644
index 93e2eb4..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_10.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,3C8.33,3,5.35,5.98,5.35,9.65       C5.35,14.64,12,22,12,22s6.65,-7.36,6.65,-12.35C18.65,5.98,15.67,3,12,3z M12,12.02c-1.31,0,-2.38,-1.06,-2.38,-2.38       S10.69,7.28,12,7.28c1.31,0,2.37,1.06,2.37,2.37S13.31,12.02,12,12.02z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_off.xml b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
index d28d347..26ebfbf 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2014 The Android Open Source Project
 
@@ -14,18 +13,19 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_qs_location_01" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_02" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_03" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_04" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_05" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_06" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_07" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_08" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_09" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_10" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_11" android:duration="16" />
-</animation-list>
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="64dp"
+        android:height="64dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#4DFFFFFF"
+        android:pathData="M24.0,13.0c2.8,0.0 5.0,2.2 5.0,5.0c0.0,1.5 -0.7,2.8 -1.7,3.7l7.3,7.3c2.0,-3.7 3.4,-7.6 3.4,-11.0c0.0,-7.7 -6.3,-14.0 -14.0,-14.0c-4.0,0.0 -7.5,1.6 -10.1,4.3l6.4,6.4C21.2,13.6 22.5,13.0 24.0,13.0zM32.7,32.2l-9.3,-9.3l-0.2,-0.2L6.5,6.0L4.0,8.5l6.4,6.4c-0.2,1.0 -0.4,2.0 -0.4,3.1c0.0,10.5 14.0,26.0 14.0,26.0s3.3,-3.7 6.8,-8.7l6.7,6.7l2.5,-2.5L32.7,32.2z"/>
+    <path
+        android:pathData="M23.5,22.9l0.0,0.0 -0.20000076,-0.19999886z"
+        android:fill="#4DFFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_on.xml b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
index 72512ac..bc73005 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2014 The Android Open Source Project
 
@@ -14,18 +13,16 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_qs_location_11" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_10" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_09" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_08" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_07" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_06" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_05" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_04" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_03" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_02" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_01" android:duration="16" />
-</animation-list>
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="64dp"
+        android:height="64dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#FFFFFFFF"
+        android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ripple_drawable.xml b/packages/SystemUI/res/drawable/ripple_drawable.xml
index d2bff42..af7941f 100644
--- a/packages/SystemUI/res/drawable/ripple_drawable.xml
+++ b/packages/SystemUI/res/drawable/ripple_drawable.xml
@@ -16,6 +16,4 @@
   -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:tint="?android:attr/colorControlHighlight"
-        android:tintMode="src_over"
-        android:pinned="true" />
+    android:color="?android:attr/colorControlHighlight" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_11.xml b/packages/SystemUI/res/drawable/stat_sys_no_sim.xml
similarity index 71%
rename from packages/SystemUI/res/drawable/ic_qs_location_11.xml
rename to packages/SystemUI/res/drawable/stat_sys_no_sim.xml
index 09a3e63..70948b7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_11.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_no_sim.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="18dp"
+        android:height="18dp"/>
 
     <viewport
         android:viewportWidth="24.0"
         android:viewportHeight="24.0"/>
 
     <path
-        android:pathData="M12,2C8.13,2,5,5.13,5,9c0,5.25,7,13,7,13s7,-7.75,7,-13       C19,5.13,15.87,2,12,2z M12,11.5c-1.38,0,-2.5,-1.12,-2.5,-2.5s1.12,-2.5,2.5,-2.5c1.38,0,2.5,1.12,2.5,2.5S13.38,11.5,12,11.5z"
-        android:fill="#4DFFFFFF"/>
+        android:fill="#4DFFFFFF"
+        android:pathData="M19.0,5.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0l-7.0,0.0L7.7,5.3L19.0,16.7L19.0,5.0zM3.7,3.9L2.4,5.2L5.0,7.8L5.0,19.0c0.0,1.1 0.9,2.0 2.0,2.0l10.0,0.0c0.4,0.0 0.7,-0.1 1.0,-0.3l1.9,1.9l1.3,-1.3L3.7,3.9z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout/battery_low.xml b/packages/SystemUI/res/layout/battery_low.xml
deleted file mode 100644
index 2373355..0000000
--- a/packages/SystemUI/res/layout/battery_low.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/layout/keyguard.xml
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/padding"
-    android:orientation="vertical"
-    android:gravity="center"
-    android:padding="16dp"
-    >
-
-    <TextView android:id="@+id/subtitle"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:textColor="#ffffffff"
-        android:gravity="start"
-        android:text="@string/battery_low_subtitle"
-        />
-    
-    <TextView android:id="@+id/level_percent"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:textColor="#ffffffff"
-        android:gravity="start"
-        android:paddingBottom="16dp"
-        />
-
-    <ImageView android:id="@+id/image"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/battery_low_battery"
-        />
-
-</LinearLayout>
-
-
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 9bf42b2..db5983b 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -46,7 +46,7 @@
         android:id="@+id/keyguard_indication_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="100dp"
+        android:layout_marginBottom="70dp"
         android:layout_gravity="bottom|center_horizontal"
         android:textStyle="italic"
         android:textColor="#ffffff"
diff --git a/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml b/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
index 463fee8..4245d49 100644
--- a/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
+++ b/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
@@ -20,4 +20,4 @@
     android:layout_height="wrap_content"
     android:layout_gravity="center_horizontal|bottom"
     android:scaleType="fitXY"
-    android:src="@drawable/recents_nav_bar_background" />
\ No newline at end of file
+    android:src="@drawable/recents_lower_gradient" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 693d8c3..4028ec3 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -77,8 +77,9 @@
     <ImageButton android:id="@+id/settings_button"
         style="@android:style/Widget.Material.Button.Borderless"
         android:layout_toStartOf="@id/multi_user_switch"
-        android:layout_width="56dp"
+        android:layout_width="48dp"
         android:layout_height="@dimen/status_bar_header_height"
+        android:layout_marginStart="8dp"
         android:src="@drawable/ic_settings_24dp"
         android:contentDescription="@string/accessibility_desc_quick_settings"/>
 
@@ -86,14 +87,14 @@
         android:layout_width="wrap_content"
         android:layout_height="@dimen/status_bar_header_height"
         android:layout_toStartOf="@id/multi_user_switch"
-        android:layout_marginEnd="4dp"
+        android:layout_marginEnd="2dp"
         />
 
     <com.android.keyguard.CarrierText
         android:id="@+id/keyguard_carrier_text"
         android:layout_width="match_parent"
         android:layout_height="@dimen/status_bar_header_height_keyguard"
-        android:layout_marginLeft="8dp"
+        android:layout_marginLeft="16dp"
         android:layout_toStartOf="@id/system_icons_container"
         android:gravity="center_vertical"
         android:ellipsize="marquee"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
index 84d64b9..e220a16 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
@@ -18,48 +18,13 @@
 <com.android.systemui.statusbar.SpeedBumpView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:focusable="true"
-    android:clickable="true"
+    android:layout_height="@dimen/speed_bump_height"
     android:visibility="gone"
     >
-    <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/speed_bump_height_collapsed"
-            android:layout_gravity="top"
-            android:orientation="horizontal">
-        <com.android.systemui.statusbar.AlphaOptimizedView
-            android:id="@+id/speedbump_line_left"
-            android:layout_width="0dp"
-            android:layout_height="1dp"
-            android:layout_weight="1"
-            android:background="#6fdddddd"
-            android:layout_gravity="center_vertical"/>
-        <com.android.systemui.statusbar.SpeedBumpDotsLayout
-                android:id="@+id/speed_bump_dots_layout"
-                android:layout_width="34dp"
-                android:layout_marginStart="8dp"
-                android:layout_marginEnd="8dp"
-                android:layout_height="match_parent"
-                android:layout_weight="0"/>
-        <com.android.systemui.statusbar.AlphaOptimizedView
-            android:id="@+id/speedbump_line_right"
-            android:layout_width="0dp"
-            android:layout_height="1dp"
-            android:layout_weight="1"
-            android:background="#6fdddddd"
-            android:layout_gravity="center_vertical"/>
-    </LinearLayout>
-    <TextView
-            android:id="@+id/speed_bump_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="top|center_horizontal"
-            android:fontFamily="sans-serif-condensed"
-            android:textSize="15sp"
-            android:singleLine="true"
-            android:textColor="#eeeeee"
-            android:visibility="invisible"
-            android:text="@string/speed_bump_explanation"
-            android:paddingTop="4dp" />
+    <com.android.systemui.statusbar.AlphaOptimizedView
+        android:id="@+id/speedbump_line"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#6fdddddd"
+        android:layout_gravity="center_vertical"/>
 </com.android.systemui.statusbar.SpeedBumpView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index a2ef9e6..3bf38cb 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen kennisgewings"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Voortdurend"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Kennisgewings"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Koppel herlaaier"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Die battery raak pap."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Battery is amper pap"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> oor"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> oor. Batteryspaarder is aan."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB-laaiery nie ondersteun nie.\nGebruik net die laaier wat verskaf is."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Batterygebruik"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Laai met USB word nie gesteun nie."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Gebruik slegs die laaier wat verskaf is."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Instellings"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Aktiveer batteryspaarder?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Begin"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Aktiveer batteryspaarder"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Om die batteryleeftyd te help verbeter, sal Batteryspaarder jou toestel se werkverrigting verminder.\n\nBatteryspaarder sal gedeaktiveer word wanneer jou toestel ingeprop word."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Instellings"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Vliegtuigmodus"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Een uur lank"</item>
     <item quantity="other" msgid="5408537517529822157">"%d uur lank"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Batteryspaarder is aan"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Toestel se werkverrigting is verminder."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Maak batteryspaarder se instellings oop"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 6aeb6d6..dea589d 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"የባትሪ ኃይል አነስተኛ ነው"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> ቀሪ"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<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="invalid_charger_title" msgid="3515740382572798460">"የUSB ኃይል መሙላት አይደገፍም።"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"የቀረበውን ኃይል መሙያ ብቻ ይጠቀሙ።"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"ቅንብሮች"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"የባህሪ ኃይል ቆጣቢው ይጀመር?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ጀምር"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"የባህሪ ኃይል ቆጣቢው ይጀመር"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"የባትሪ በህይወት የመቆየት ጊዜን ለማሻሻል እንዲያግዝ፣ የባትሪ ኃይል ቆጣቢው የመሳሪያዎን የመስራት አቅም ይቀንሰዋል።\n\nየባትሪ ኃይል ቆጣቢው መሳሪያዎ የተሰካ ሲሆን ይሰናከላል።"</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"ለአንድ ሰዓት"</item>
     <item quantity="other" msgid="5408537517529822157">"ለ%d ሰዓቶች"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"የባትሪ ኃይል ቆጣቢ በርቷል"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"የመሳሪያው የአሰራር ብቃት ተቀንሷል።"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"የባትሪ ኃይል ቆጣቢ ቅንብሮች"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 1aec6fd..f369d12 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"البطارية منخفضة"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"المتبقي: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"يتبقى <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="invalid_charger_title" msgid="3515740382572798460">"‏لا يمكن إجراء الشحن عبر USB."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"لا تستخدم سوى الشاحن المزوّد."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"الإعدادات"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"هل تريد بدء وضع توفير الطاقة؟"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"بدء"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"بدء وضع توفير الطاقة"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"للمساعدة في إطالة عمر البطارية، فإن وضع توفير الطاقة سيقلل من أداء جهازك.\n\nسيتم تعطيل وضع توفير الطاقة عند توصيل جهازك بالشاحن."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"لمدة ساعة واحدة"</item>
     <item quantity="other" msgid="5408537517529822157">"‏لمدة %d من الساعات"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"وضع توفير الطاقة قيد التشغيل"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"تم تقليل أداء الجهاز."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"فتح إعدادات وضع توفير الطاقة"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e16cdd3..2c3837a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Батерията е изтощена"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Остава: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Остава: <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="invalid_charger_title" msgid="3515740382572798460">"Зареждането през USB не се поддържа."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Използвайте само предоставеното зарядно устройство."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Настройки"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Да се стартира ли режимът за запазване на батерията?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Стартиране"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Стартиране на режима за запазване на батерията"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"С цел удължаване на живота на батерията режимът за запазването й ще намали ефективността на устройството ви.\n\nКогато то е включено в захранването, режимът ще се деактивира."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"За един час"</item>
     <item quantity="other" msgid="5408537517529822157">"За %d часа"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Режимът за запазване на батерията е включен"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Ефективността на устройството е намалена."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Отваряне на настройките за режима за запазване на батерията"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index ad08dab..c0b62d5 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Cap notificació"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continu"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificacions"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Connecta el carregador"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"La bateria comença a estar baixa."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Queda poca bateria"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Queda un <xliff:g id="NUMBER">%d%%</xliff:g>. La funció Estalvi de bateria està activada."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Càrrega d\'USB no admesa.\nUtilitza només el carregador proporcionat."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Ús de la bateria"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"La càrrega per USB no és compatible."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Fes servir només el carregador proporcionat amb el dispositiu."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Configuració"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vols iniciar la funció Estalvi de bateria?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Inicia"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Inicia la funció Estalvi de bateria"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"La funció Estalvi de bateria reduirà el rendiment del dispositiu per tal d\'augmentar la durada de la bateria.\n\nAquesta funció es desactivarà quan el dispositiu estigui connectat."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configuració"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode d\'avió"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Durant una hora"</item>
     <item quantity="other" msgid="5408537517529822157">"Durant %d hores"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"La funció Estalvi de bateria està activada."</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"S\'ha reduït el rendiment del dispositiu."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Obre la configuració de la funció Estalvi de bateria"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 5a08251..f7e3b14 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žádná oznámení"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Probíhající"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Oznámení"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Připojte nabíječku"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterie je vybitá."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Baterie je slabá"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Zbývá <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Zbývá <xliff:g id="NUMBER">%d%%</xliff:g>. Režim Úspora baterie je zapnutý."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Nabíjení pomocí rozhraní USB není podporováno.\nPoužívejte pouze nabíječku, která byla dodána se zařízením."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Využití baterie"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Nabíjení přes USB není podporováno."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Používejte pouze nabíječku, která je součástí balení."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Nastavení"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Aktivovat režim Úspora baterie?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Spustit"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Aktivovat režim Úspora baterie"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"V režimu Úspora baterie se omezí výkon zařízení, aby se tak prodloužila výdrž baterie.\n\nRežim Úspora baterie se deaktivuje, když bude zařízení zapojeno do zásuvky."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavení"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Režim V letadle"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Na jednu hodinu"</item>
     <item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Režim Úspora baterie je zapnutý."</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Výkon zařízení je snížen."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otevřít nastavení režimu Úspora baterie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 50c3dbb..05b72ce 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -32,11 +32,17 @@
     <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>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er ved at være fladt."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Batteriniveauet er lavt"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tilbage"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> tilbage. Batteribesparende er slået til."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Opladning via USB understøttes ikke.\nBrug kun den medfølgende oplader."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Batteriforbrug"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB-opladning understøttes ikke."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Brug kun den oplader, der føler med."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Indstillinger"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vil du starte Batteribesparende?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Startet"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start Batteribesparende"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"For at hjælpe med at forbedre batteriets levetid, reducerer Batteribesparende enhedens ydeevne.\n\nBatteribesparende slukkes, når strømstikket er sat i."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Indstillinger"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flytilstand"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"I én time"</item>
     <item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Batteribesparende er slået til"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Enhedens ydeevne reduceres."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Åbn indstillinger for Batteribesparende"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 27523d8..6e6280c 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Keine Benachrichtigungen"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktuell"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Benachrichtigungen"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Ladegerät anschließen"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Akku ist fast leer."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Akku ist schwach"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Noch <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Noch <xliff:g id="NUMBER">%d%%</xliff:g>. Energiesparmodus ist aktiviert."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt.\nVerwenden Sie das mitgelieferte Aufladegerät."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Akkuverbrauch"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Laden per USB wird nicht unterstützt."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Verwenden Sie nur das im Lieferumfang enthaltene Ladegerät."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Einstellungen"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Energiesparmodus starten?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Starten"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Energiesparmodus starten"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Im Energiesparmodus wird zur Schonung des Akkus die Leistung des Geräts herabgesetzt.\n\nSobald Ihr Gerät an eine Stromquelle angeschlossen ist, wird der Energiesparmodus deaktiviert."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Einstellungen"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flugmodus"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Für eine Stunde"</item>
     <item quantity="other" msgid="5408537517529822157">"Für %d Stunden"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Energiesparmodus ist aktiviert"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Die Geräteleistung wurde herabgesetzt."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Einstellungen für den Energiesparmodus öffnen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c0d586e..a99e91e 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Χαμηλή στάθμη μπαταρίας"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Απομένει <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Απομένει <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="invalid_charger_title" msgid="3515740382572798460">"Δεν υποστηρίζεται η φόρτιση μέσω USB."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Χρήση μόνο του παρεχόμενου φορτιστή."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Ρυθμίσεις"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Έναρξη Εξοικονόμησης μπαταρίας;"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Έναρξη"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Έναρξη Εξοικονόμησης μπαταρίας"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Για να συμβάλει στη βελτίωση της διάρκειας ζωής της μπαταρίας, η Εξοικονόμηση μπαταρίας θα μειώσει την απόδοση της συσκευής σας.\n\nΗ Εξοικονόμηση μπαταρίας θα απενεργοποιηθεί όταν η συσκευή σας συνδεθεί για φόρτιση."</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>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Για μία ώρα"</item>
     <item quantity="other" msgid="5408537517529822157">"Για %d ώρες"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Η Εξοικονόμηση μπαταρίας είναι ενεργή"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Η απόδοση της συσκευής μειώνεται."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Άνοιγμα ρυθμίσεων Εξοικονόμησης μπαταρίας"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index df8698c..0938b28 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Battery is low"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> remaining"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> remaining. Battery saver is on."</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="invalid_charger_title" msgid="3515740382572798460">"USB charging not supported."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Use only the supplied charger."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Settings"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Start battery saver?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Start"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start battery saver"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"For one hour"</item>
     <item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Battery saver is on"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Device performance is reduced."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Open battery saver settings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index df8698c..0938b28 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Battery is low"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> remaining"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> remaining. Battery saver is on."</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="invalid_charger_title" msgid="3515740382572798460">"USB charging not supported."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Use only the supplied charger."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Settings"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Start battery saver?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Start"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start battery saver"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"For one hour"</item>
     <item quantity="other" msgid="5408537517529822157">"For %d hours"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Battery saver is on"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Device performance is reduced."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Open battery saver settings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 5ce867e..cfa809c 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No hay notificaciones"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continuo"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Conecta el cargador."</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Hay poca batería."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Batería baja"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Quedan <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> restante. El ahorro de batería está activado."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"No admite la carga USB.\nUsa sólo el cargador provisto."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Uso de la batería"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"No se admite la carga por USB."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Usa solo el cargador suministrado."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Configuración"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"¿Quieres iniciar el ahorro de batería?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar ahorro de batería"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ayudar a mejorar la duración de la batería, el ahorro de batería reducirá el rendimiento del dispositivo.\n\nEsta función se inhabilitará cuando el dispositivo esté conectado."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configuración"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo avión"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Durante una hora"</item>
     <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Ahorro de batería activado"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Rendimiento del dispositivo reducido"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir configuración del ahorro de batería"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index c25e5cd..242a7d0 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No tienes notificaciones"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Entrante"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Conecta el cargador"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Se está agotando la batería."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Nivel de batería bajo"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> restante. Ahorro de batería activado."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"No se admite la carga por USB.\nUtiliza solo el cargador proporcionado."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Uso de la batería"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"No se admite la carga por USB."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Utiliza solo el cargador proporcionado."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Ajustes"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"¿Iniciar ahorro de batería?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar ahorro de batería"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ayudar a mejorar la duración de la batería, la función de ahorro de energía reducirá el rendimiento del dispositivo.\n\nEsta función estará inhabilitada cuando el dispositivo esté enchufado."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ajustes"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo avión"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Durante una hora"</item>
     <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Ahorro de batería activado"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Rendimiento del dispositivo reducido."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir ajustes de la función de ahorro de batería"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 21cb2f1..bc9a6e6 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Aku hakkab tühjaks saama"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> on alles"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Alles: <xliff:g id="NUMBER">%d%%</xliff:g>. Akusäästja on sisse lülitatud."</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="invalid_charger_title" msgid="3515740382572798460">"USB-ga laadimist ei toetata."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Kasutage ainult kaasasolevat laadijat."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Seaded"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Kas käivitada akusäästja?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Käivita"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Käivita akusäästja"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Aku tööea parandamiseks vähendab akusäästja teie seadme jõudlust.\n\nKui seade ühendatakse toiteallikaga, keelatakse akusäästja."</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>
@@ -239,4 +245,7 @@
     <item quantity="one" msgid="3480040795582254384">"Üheks tunniks"</item>
     <item quantity="other" msgid="5408537517529822157">"%d tunniks"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Akusäästja on sisse lülitatud"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Seadme jõudlust on vähendatud."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ava akusäästja seaded"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index a0d1819..8495828 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"شارژ باتری کم است"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> باقیمانده است"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<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="invalid_charger_title" msgid="3515740382572798460">"‏شارژ با USB پشتیبانی نمی‌شود."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"فقط از شارژر ارائه شده استفاده کنید."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"تنظیمات"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ذخیره کننده باتری شروع شود؟"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"شروع"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"شروع ذخیره کننده باتری"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ذخیره کننده باتری برای کمک به بهبود عمر باتری شما، عملکرد دستگاهتان را کاهش می‌دهد.\n\nهنگامی که دستگاه شما به برق وصل است، ذخیره کننده باتری خاموش می‌شود."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"برای یک ساعت"</item>
     <item quantity="other" msgid="5408537517529822157">"‏برای %d ساعت"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"ذخیره کننده باتری روشن است."</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"عملکرد دستگاه کاهش یافته است."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"باز کردن تنظیمات ذخیره کننده باتری"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 0a0cdd9..c73caf4 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ei ilmoituksia"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Käynnissä olevat"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Ilmoitukset"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Kytke laturi"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Akun virta on vähissä."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Akku on vähissä"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> jäljellä"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> jäljellä. Virransäästö on käytössä."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB-latausta ei tueta.\nKäytä laitteen mukana tullutta laturia."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Akun käyttö"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB-latausta ei tueta."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Käytä vain laitteen mukana toimitettua laturia."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Asetukset"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Käynnistetäänkö virransäästö?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Käynnistä"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Käynnistä virransäästö"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Virransäästötoiminto pidentää akun kestoa vähentämällä laitteen virrankulutusta.\n\nLaitteen kytkeminen virtalähteeseen poistaa virransäästön käytöstä."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Asetukset"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lentokonetila"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Tunniksi"</item>
     <item quantity="other" msgid="5408537517529822157">"%d tunniksi"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Virransäästö on käytössä"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Laitteen virrankulutusta vähennetään."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Avaa virransäästöasetukset"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index c3b53b5..179b54d 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Pile faible"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant(s)"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Il reste : <xliff:g id="NUMBER">%d%%</xliff:g>. La fonction Économie d\'énergie est activée."</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="invalid_charger_title" msgid="3515740382572798460">"Le chargement par USB n\'est pas pris en charge."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Utilisez uniquement le chargeur fourni."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Paramètres"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Démarrer la fonction Économie d\'énergie?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Démarrer"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Démarrer la fonction Économie d\'énergie"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pour vous aider à prolonger l\'autonomie de votre appareil, la fonction Économie d\'énergie réduit les performances de l\'appareil.\n\nElle se désactive lorsque l\'appareil est branché."</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>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Pendant une heure"</item>
     <item quantity="other" msgid="5408537517529822157">"Pendant %d heures"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"La fonction Économie d\'énergie est activée"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Les performances de l\'appareil sont réduites."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ouvrir les paramètres d\'économie d\'énergie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index ab1f30b..3334125 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Batterie faible"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant(s)"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Il reste <xliff:g id="NUMBER">%d%%</xliff:g>. L\'économiseur de batterie est activé."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Chargement USB non disponible.\nVous devez utiliser le chargeur fourni."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Utilisation de la batterie"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Chargeur USB non compatible."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Veuillez n\'utiliser que le chargeur fourni."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Paramètres"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Démarrer l\'économiseur de batterie ?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Démarrer"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Démarrer l\'économiseur de batterie"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pour vous aider à prolonger l\'autonomie de la batterie, les performances de l\'appareil sont réduites.\n\nL\'économiseur de batterie est désactivé lorsque l\'appareil est branché."</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>
@@ -234,7 +240,7 @@
     <string name="phone_hint" msgid="3101468054914424646">"Balayer l\'écran vers la droite pour accéder au téléphone"</string>
     <string name="camera_hint" msgid="5241441720959174226">"Balayer l\'écran vers la gauche pour accéder à l\'appareil photo"</string>
     <string name="zen_mode_forever" msgid="7420011936770086993">"Jusqu\'à la désactivation"</string>
-    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours… (chargé à 100 % dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
   <plurals name="zen_mode_duration_minutes">
     <item quantity="one" msgid="9040808414992812341">"Pendant une minute"</item>
     <item quantity="other" msgid="6924190729213550991">"Pendant %d minutes"</item>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Pendant une heure"</item>
     <item quantity="other" msgid="5408537517529822157">"Pendant %d heures"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"L\'économiseur de batterie est activé"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Les performances de l\'appareil sont réduites."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Ouvrir les paramètres de l\'économiseur de batterie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 8b1eb55b..fe28ec5 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"बैटरी कम है"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> शेष"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<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="invalid_charger_title" msgid="3515740382572798460">"USB चार्जिंग समर्थित नहीं है."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"केवल आपूर्ति किए गए चार्जर का उपयोग करें."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"सेटिंग"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"बैटरी सेवर प्रारंभ करें?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"प्रारंभ करें"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"बैटरी सेवर प्रारंभ करें"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"बैटरी का जीवनकाल बेहतर बनाने में सहायता के लिए, बैटरी सेवर आपके उपकरण के प्रदर्शन को कम कर देगा.\n\nआपका उपकरण प्लग किए जाने पर बैटरी सेवर अक्षम हो जाएगा."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"एक घंटे के लिए"</item>
     <item quantity="other" msgid="5408537517529822157">"%d घंटे के लिए"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"बैटरी सेवर चालू है"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"उपकरण का प्रदर्शन कम हो गया है."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"बैटरी सेवर सेटिंग चालू करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 953e077b..4ee3e32 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bez obavijesti"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"U tijeku"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Obavijesti"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Priključite punjač"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterija će uskoro biti potrošena."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Niska razina baterije"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> preostalo"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Preostalo je <xliff:g id="NUMBER">%d%%</xliff:g>. Štednja baterije je uključena."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB punjenje nije podržano.\nUpotrijebite samo priloženi punjač."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Iskorištenost baterije"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Punjenje putem USB-a nije podržano."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Upotrebljavajte samo priloženi punjač."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Postavke"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Želite li pokrenuti štednju baterije?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Kreni"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Pokretanje štednje baterije"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Da bi baterija trajala dulje, Štednja baterije smanjit će intenzitet rada uređaja.\n\nŠtednja baterije onemogućit će se kada je uređaj priključen."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Postavke"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Način rada u zrakoplovu"</string>
@@ -186,8 +192,8 @@
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (broj uređaja: <xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth isključen"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Svjetlina"</string>
-    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatsko usmjerenje"</string>
-    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Usmjerenje je zaključano"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatsko izmjenjivanje"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Izmjenjivanje je zaključano"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Okomito"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Vodoravno"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Način unosa"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Jedan sat"</item>
     <item quantity="other" msgid="5408537517529822157">"%d h"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Štednja baterije je uključena"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Uređaj radi smanjenim intenzitetom."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otvaranje postavki štednje baterije"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index ad2bc5c..95af816 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nincs értesítés"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Folyamatban van"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Értesítések"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Csatlakoztassa a töltőt"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Az akkufeszültség alacsony."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Alacsony az energiaszint"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> maradt"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> maradt. Az Akkumulátorkímélő mód bekapcsol."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Az USB-n keresztüli töltés nincs támogatva.\nHasználja a kapott töltőt."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Akkumulátorhasználat"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Az USB-n keresztüli töltés nem támogatott."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Kizárólag a tartozékként kapott töltőt használja."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Beállítások"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Elindítja az Akkumulátorkímélő módot?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Indítás"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Akkumulátorkímélő mód indítása"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Az Akkumulátorkímélő mód csökkenti az eszköz teljesítményét, hogy növelje az akkumulátor üzemidejét.\n\nAz eszköz töltésekor az Akkumulátorkímélő üzemmód kikapcsol."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Beállítások"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Repülőgép üzemmód"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Egy órán át"</item>
     <item quantity="other" msgid="5408537517529822157">"%d órán át"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Akkumulátorkímélő mód bekapcsolva"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Az eszköz teljesítménye lecsökkentve."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Akkumulátorkímélő mód beállításainak megnyitása"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index e15730e..637d85f 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Մարտկոցը լիցքաթափվում է"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"մնում է <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Մնաց <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="invalid_charger_title" msgid="3515740382572798460">"USB լիցքավորումը չի աջակցվում:"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Օգտագործեք միայն մատակարարի տրամադրած լիցքավորիչը:"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Կարգավորումներ"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Գործարկե՞լ մարտկոցի տնտեսումը:"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Մեկնարկել"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Գործարկել մարտկոցի տնտեսումը"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Մարտկոցի տնտեսումը կնվազեցնի ձեր սարքի կատարողականը՝ մարտկոցն ավելի երկար օգտագործելու համար:\n\nՄարտկոցի տնտեսումը կանջատվի, հենց սարքը միացնեք հոսանքի աղբյուրին:"</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Մեկ ժամ"</item>
     <item quantity="other" msgid="5408537517529822157">"%d ժամ"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Մարտկոցի տնտեսումը միացված է"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Սարքի կատարողականը նվազեցված է:"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Բացել մարտկոցի տնտեսման կարգավորումները"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 08da900..3cd82a7 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tidak ada pemberitahuan"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Berkelanjutan"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Pemberitahuan"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Hubungkan pengisi daya"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterai semakin lemah."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Baterai lemah"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tersisa"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Tersisa <xliff:g id="NUMBER">%d%%</xliff:g>. Penghemat baterai aktif."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Pengisian daya USB tidak didukung.\nGunakan hanya pengisi daya yang disediakan."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Penggunaan baterai"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Pengisian daya USB tidak didukung."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Hanya gunakan pengisi daya yang disediakan."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Setelan"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Mulai penghemat baterai?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Mulai"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Mulai penghemat baterai"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Untuk membantu meningkatkan masa pakai baterai, Penghemat baterai akan mengurangi kinerja perangkat Anda.\n\nPenghemat baterai akan dinonaktifkan saat perangkat dihubungkan dengan sumber daya."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setelan"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode pesawat"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Selama satu jam"</item>
     <item quantity="other" msgid="5408537517529822157">"Selama %d jam"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Penghemat baterai aktif"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Kinerja perangkat dikurangi."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buka setelan penghemat baterai"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 16ebe4c8..b62d75a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nessuna notifica"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"In corso"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifiche"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Collega il caricabatterie"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteria quasi scarica."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Batteria quasi scarica"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> rimanente"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> rimanente. La funzione Risparmio batteria è attiva."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Ricarica tramite USB non supportata.\nUtilizza solo il caricatore in dotazione."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Utilizzo batteria"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Ricarica tramite USB non supportata."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Utilizza solo il caricabatterie fornito in dotazione."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Impostazioni"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Avviare risparmio batteria?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Avvia"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Avvia risparmio batteria"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Per aumentare la durata della batteria, Risparmio batteria riduce le prestazioni del tuo dispositivo.\n\nRisparmio batteria si disattiva quando il dispositivo è collegato alla corrente."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Impostazioni"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modalità aereo"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Per un\'ora"</item>
     <item quantity="other" msgid="5408537517529822157">"Per %d ore"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Risparmio batteria attivo"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Le prestazioni del dispositivo sono ridotte."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Apri impostazioni risparmio batteria"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 49d7b40..e1e7e00 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"עוצמת הסוללה נמוכה"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"נותרו <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"נותרו <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="invalid_charger_title" msgid="3515740382572798460">"‏טעינה בחיבור USB אינה נתמכת."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"השתמש רק במטען שסופק."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"הגדרות"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"האם להפעיל את \'חיסכון בסוללה\'?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"התחל"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"הפעל את \'חיסכון בסוללה\'"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"כדי לעזור בהארכת חיי הסוללה, תכונת \'חיסכון בסוללה\' תצמצם את פעילות המכשיר.\n\nתכונת \'חיסכון בסוללה\' תושבת כשהמכשיר יחובר לחשמל."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"למשך שעה אחת"</item>
     <item quantity="other" msgid="5408537517529822157">"‏למשך %d שעות"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"תכונת \'חיסכון בסוללה\' פועלת"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"פעילות המכשיר צומצמה."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"פתח את ההגדרות של \'חיסכון בסוללה\'"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 4a2a3c1..b6359e9 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"電池残量が少なくなっています"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"残り<xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"残量が<xliff:g id="NUMBER">%d%%</xliff:g>です。バッテリーセーバーはONです。"</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB充電には対応していません。\n付属の充電器をお使いください。"</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"電池使用量"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB充電には対応していません。"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"専用の充電器のみを使用してください。"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"設定"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"バッテリーセーバーを開始しますか?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"開始"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"バッテリーセーバーを開始"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを制限します。\n\n端末が電源に接続されているときはバッテリーセーバーが無効になります。"</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>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"1時間"</item>
     <item quantity="other" msgid="5408537517529822157">"%d時間"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"バッテリーセーバーがON"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"端末のパフォーマンスが制限されています。"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"バッテリーセーバーの設定を開く"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 079fc7f..973cd63 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"ბატარეა იწურება"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"დარჩენილია <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"დარჩენილია <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="invalid_charger_title" msgid="3515740382572798460">"USB დატენვა მხარდაჭერილი არ არის."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"გამოიყენეთ მხოლოდ მოყოლილი დამტენი."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"პარამეტრები"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"გსურთ ბატარეის დამზოგის დაწყება?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"დაწყება"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"ბატარეის დამზოგის დაწყება"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ბატარეის მოქმედების გასახანგრძლივებლად ბატარეის დამზოგი შეამცირებს თქვენი მოწყობილობის წარმადობას.\n\nბატარეის დამზოგი გამოირთვება, როდესაც მოწყობილობას ელკვებაზე მიაერთებთ."</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>
@@ -120,7 +126,7 @@
     <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_desc_connecting" msgid="3812924520316280149">"უკავშრდება."</string>
+    <string name="accessibility_desc_connecting" msgid="3812924520316280149">"უკავშირდება."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"ერთი საათით"</item>
     <item quantity="other" msgid="5408537517529822157">"%d საათით"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"ბატარეის დამზოგი ჩართულია"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"მოწყობილობის წარმადობა შემცირებულია."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ბატარეის დამზოგის პარამეტრების გახსნა"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index be41e50..8b0e3b1 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"ជិត​អស់​ថ្ម​ហើយ"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"នៅ​សល់ <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"នៅ​សល់ <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="invalid_charger_title" msgid="3515740382572798460">"មិន​គាំទ្រ​ការ​បញ្ចូល​ថ្ម​តាម​យូអេសប៊ី​ទេ។"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"ប្រើ​តែ​ឧបករណ៍​បញ្ចូល​ថ្ម​ដែល​បាន​ផ្ដល់​ឲ្យ។"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"ការកំណត់"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ចាប់ផ្ដើម​កម្មវិធី​សន្សំ​ថ្ម?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ចាប់ផ្ដើម"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"ចាប់ផ្ដើម​កម្មវិធី​សន្សំ​ថ្ម"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ដើម្បី​ជួយ​បង្កើន​អាយុកាល​ថ្ម កម្មវិធី​សន្សំ​ថ្ម​នឹង​កាត់បន្ថយ​ការ​អនុវត្ត​​នៃ​ឧបករណ៍​របស់​អ្នក។\n\nកម្មវិធី​សន្សំ​ថ្ម​នឹង​បិទ​នៅ​ពេល​ឧបករណ៍​របស់​អ្នក​ត្រូវ​បាន​ដោត​បញ្ចូល​ថ្ម។"</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>
@@ -64,7 +70,7 @@
     <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_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>
@@ -141,7 +147,7 @@
     <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_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>
@@ -191,7 +197,7 @@
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"បញ្ឈរ"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ទេសភាព"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"វិធីសាស្ត្រ​បញ្ចូល"</string>
-    <string name="quick_settings_location_label" msgid="5011327048748762257">"ទី​តាំង​"</string>
+    <string name="quick_settings_location_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>
@@ -215,7 +221,7 @@
     <string name="recents_empty_message" msgid="7883614615463619450">"មិនមាន​​កម្មវិធី​ថ្មីៗ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"ព័ត៌មាន​កម្មវិធី"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
-    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញ​អាច​\nត្រូវ​បាន​ត្រួតពិនិត្យ​"</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"សម្រាប់​មួយ​ម៉ោង"</item>
     <item quantity="other" msgid="5408537517529822157">"សម្រាប់ %d ម៉ោង"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"កម្មវិធី​សន្សំ​ថ្ម​គឺ​បើក"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ការ​អនុវត្ត​ឧបករណ៍​ត្រូវ​បាន​កាត់​បន្ថយ។"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"បើក​ការ​កំណត់​កម្មវិធី​សន្សំ​ថ្ម"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 5fdc4e1..5435a7b 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -32,11 +32,19 @@
     <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_title" msgid="6456385927409742437">"배터리 부족"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> 남음"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for battery_low_percent_format_saver_started (6534746636002666456) -->
+    <skip />
     <string name="invalid_charger" msgid="4549105996740522523">"USB 충전이 지원되지 않습니다.\n제공된 충전기만 사용하세요."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"배터리 사용량"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB 충전은 지원되지 않습니다."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"제공된 충전기만 사용하세요."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"설정"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"배터리 세이버를 시작할까요?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"시작"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"배터리 세이버 시작"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"배터리 세이버는 기기의 성능을 저하시켜 배터리 수명을 늘립니다.\n\n기기에 전원이 연결되면 배터리 세이버는 사용 중지됩니다."</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>
@@ -241,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"1시간 동안"</item>
     <item quantity="other" msgid="5408537517529822157">"%d시간 동안"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"배터리 세이버 사용 중"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"기기의 성능이 저하됩니다."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"배터리 세이버 설정 열기"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index abcab9e..2671314 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"ແບັດເຕີຣີ​ເຫຼືອ​ໜ້ອຍ"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"ຍັງເຫຼືອອີກ <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"ຍັງເຫຼືອ <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="invalid_charger_title" msgid="3515740382572798460">"ບໍ່​ຮອງຮັບ​ການ​ສາກ​ຜ່ານ USB."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"ໃຊ້​ສະເພາະ​ສາຍ​ສາກ​ທີ່​ມາ​ກັບ​ເຄື່ອງ."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"​ການ​ຕັ້ງ​ຄ່າ"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"ເລີ່ມ​ໂຕປະຢັດ​ແບັດເຕີຣີ​ບໍ?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ເລີ່ມ"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"ເລີ່ມ​ໂຕ​ປະຢັດ​ແບັດເຕີຣີ"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"ເພື່ອ​ຊ່ວຍ​ຢືດ​ອາຍຸ​ແບັດເຕີຣີ, ໂຕ​ປະຢັດ​ແບັດເຕີຣີ​ຈະ​ຫຼຸດ​ປະສິດທິພາບ​ຂອງ​ອຸປະກອນ​ທ່ານ​ລົງ.\n\nໂຕ​ປະຢັດ​ແບັດເຕີຣີ​ຈະ​ຖືກ​ປິດ​ການນຳໃຊ້​ໂດຍ​ອັດຕະໂນມັດ​ເມື່ອ​ທ່ານ​ສຽບ​ສາຍ​ສາກ​ອຸປະກອນ​ຂອງ​ທ່ານ."</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>
@@ -231,7 +237,7 @@
     <string name="keyguard_unlock" msgid="8043466894212841998">"ເລື່ອນ​ຂຶ້ນ​ເພື່ອ​ປົດ​ລັອກ"</string>
     <string name="phone_hint" msgid="3101468054914424646">"ປັດ​ຂວາ​ເພື່ອ​ໃຊ້​ໂທ​ລະ​ສັບ"</string>
     <string name="camera_hint" msgid="5241441720959174226">"ປັດ​ຊ້າຍ​ເພື່ອ​ໃຊ້​ກ້ອງ"</string>
-    <string name="zen_mode_forever" msgid="7420011936770086993">"ຈົນກວ່າ​ທ່ານ​ຈະ​ປິດ​"</string>
+    <string name="zen_mode_forever" msgid="7420011936770086993">"ຈົນກວ່າ​ທ່ານ​ຈະ​ປິດ"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ກຳ​ລັງ​ສາກ​ໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າ​ຈ​ະ​ເຕັມ)"</string>
   <plurals name="zen_mode_duration_minutes">
     <item quantity="one" msgid="9040808414992812341">"ເປັນ​ເວລາ​ນຶ່ງ​ນາ​ທີ"</item>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"ເປັນ​ເວລາ​ນຶ່ງ​ຊົ່ວ​ໂມງ"</item>
     <item quantity="other" msgid="5408537517529822157">"ເປັນ​ເວລາ %d ຊົ່ວ​ໂມງ"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"ເປີດ​ໃຊ້​ໂຕ​ປະຢັດ​ແບັດເຕີຣີ​ແລ້ວ"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ປະສິດທິພາບ​ຂອງ​ອຸປະກອນ​ຖືກ​ຫຼຸດ​ລົງ​ແລ້ວ."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"ເປີດ​ການ​ຕັ້ງຄ່າ​ໂຕ​ປະຢັດ​ແບັດເຕີຣີ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4818a1f..6563d45 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nėra įspėjimų"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Vykstantys"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Įspėjimai"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Prijunkite įkroviklį"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Akumuliatorius senka."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Akumuliatorius senka"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Liko <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Liko <xliff:g id="NUMBER">%d%%</xliff:g>. Akumuliatoriaus tausojimo priemonė įjungta."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB krovimas nepalaikomas.\nNaudokite tik pateiktą įkroviklį."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Akumuliatoriaus naudojimas"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB įkrovimas nepalaikomas."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Naudokite tik pateiktą kroviklį."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Nustatymai"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Paleisti akumuliatoriaus tausojimo priemonę?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Paleisti"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Paleisti akumuliatoriaus tausojimo priemonę"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Kad padėtų pailginti akumuliatoriaus naudojimo trukmę, akumuliatoriaus tausojimo priemonė sumažins įrenginio našumą.\n\nAkumuliatoriaus tausojimo priemonė bus išjungta, kai įrenginys bus prijungtas prie maitinimo šaltinio."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nustatymai"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lėktuvo režimas"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"1 val."</item>
     <item quantity="other" msgid="5408537517529822157">"%d val."</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Akumuliatoriaus tausojimo priemonė įjungta"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Įrenginio našumas sumažintas."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Atidaryti akumuliatoriaus tausojimo priemonės nustatymus"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 5a3a563..4c4031e 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nav paziņojumu"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Notiekošs"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Paziņojumi"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Pievienojiet uzlādes ierīci."</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Akumulators drīz izlādēsies."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Zems akumulatora enerģijas līmenis"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Atlicis: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Atlikuši <xliff:g id="NUMBER">%d%%</xliff:g>. Ir ieslēgts akumulatora enerģijas taupīšanas režīms."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB lādēšana netiek atbalstīta.\nIzmantojiet tikai komplektā iekļauto lādētāju."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Akumulatora lietojums"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB uzlāde netiek atbalstīta."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Izmantojiet tikai komplektā iekļauto lādētāju."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Iestatījumi"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vai ieslēgt akumulatora enerģijas taupīšanas režīmu?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Ieslēgt"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Ieslēgt akumulatora enerģijas taupīšanas režīmu"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Lai paildzinātu akumulatora darbības laiku, akumulatora enerģijas taupīšanas režīmā tiks pazemināta ierīces veiktspēja.\n\nAkumulatora enerģijas taupīšanas režīms tiks atspējots, kad ierīce tiks pievienota uzlādes avotam."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Iestatījumi"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lidmašīnas režīms"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Vienu stundu"</item>
     <item quantity="other" msgid="5408537517529822157">"%d h"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Ieslēgts akumulatora enerģijas taupīšanas režīms"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Ierīces veiktspēja ir pazemināta."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Atvērt akumulatora enerģijas taupīšanas režīma iestatījumus"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 9c02521..2bb37f6 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Батерей дуусаж байна"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> үлдсэн"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<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="invalid_charger_title" msgid="3515740382572798460">"USB-р цэнэглэх дэмжигддэггүй."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Зөвхөн зориулалтын ирсэн цэнэглэгч ашиглана уу."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Тохиргоо"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Батерей хэмнэгчийг эхлүүлэх үү?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Эхлэх"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Батерей хэмнэгчийг эхлүүлэх"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Батарейны ашиглалтыг уртасгахын тулд Батарей хэмнэгч нь таны төхөөрөмжийн ажиллагааг бууруулах болно.\n\nБатарей хэмнэгч нь та төхөөрөмжөө цэнэглэх үед унтарна."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Нэг цагийн турш"</item>
     <item quantity="other" msgid="5408537517529822157">"%d цагийн турш"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Батерей хэмнэгч асаалттай"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Төхөөрөмжийн ажиллагааг бууруулсан."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Батерей хэмнэгчийн тохиргоог нээх"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 7ff19ba..7f46211 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Bateri lemah"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Berbaki <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Tinggal <xliff:g id="NUMBER">%d%%</xliff:g>. Penjimat bateri dihidupkan."</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="invalid_charger_title" msgid="3515740382572798460">"Pengecasan USB tidak disokong."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Gunakan pengecas yang dibekalkan sahaja."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Tetapan"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Mulakan penjimat bateri?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Mula"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Mulakan penjimat bateri"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Untuk membantu meningkatkan hayat bateri, penjimat Bateri akan mengurangkan prestasi peranti anda.\n\nPenjimat bateri akan dilumpuhkan apabila peranti anda disambungkan kepada sumber kuasa."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Selama satu jam"</item>
     <item quantity="other" msgid="5408537517529822157">"Selama %d jam"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Penjimat bateri dihidupkan"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Prestasi peranti dikurangkan."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buka tetapan penjimat bateri"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f0316fc..91b14da 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen varslinger"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktiviteter"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Varslinger"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Koble til lader"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Lavt batterinivå."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Batterikapasiteten er lav"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> gjenværende"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> gjenstår. Batterisparing er på."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB-lading støttes ikke.\nBruk kun den medfølgende laderen."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Batteribruk"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Lading via USB støttes ikke."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Bruk bare den tilhørende laderen."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Innstillinger"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vil du starte batterisparing?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Start"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Start batterisparing"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"For å spare batteritid reduserer Batterisparing enhetens ytelse.\n\nBatterisparing deaktiveres når enheten er koblet til en lader."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Innstillinger"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Trådløse nettverk"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flymodus"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"I én time"</item>
     <item quantity="other" msgid="5408537517529822157">"I %d timer"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Batterisparing er på"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Enhetsytelsen er redusert."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Åpen innstilling for batterisparing"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 198eb8e..fd7337e 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen meldingen"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actief"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meldingen"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Sluit de oplader aan"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"De accu raakt leeg."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Accu is bijna leeg"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> resterend"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> resterend. Accubesparing is ingeschakeld."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Opladen via USB niet ondersteund.\nGebruik alleen de bijgeleverde oplader."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Accugebruik"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Opladen via USB wordt niet ondersteund."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Gebruik alleen de bijgeleverde oplader."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Instellingen"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Accubesparing starten?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Starten"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Accubesparing starten"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Om de gebruiksduur van de accu te verbeteren, beperkt Accubesparing de prestaties van uw apparaat.\n\nAccubesparing wordt uitgeschakeld wanneer uw apparaat wordt aangesloten op een stopcontact."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Instellingen"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wifi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Vliegmodus"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Eén uur"</item>
     <item quantity="other" msgid="5408537517529822157">"%d uur"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Accubesparing is ingeschakeld"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"De prestaties van het apparaat worden beperkt."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Instellingen voor Accubesparing openen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index a83c07d..4d582e2 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Brak powiadomień"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Bieżące"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Powiadomienia"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Podłącz ładowarkę"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria wkrótce się rozładuje."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Bateria jest słaba"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Pozostało: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Zostało <xliff:g id="NUMBER">%d%%</xliff:g>. Oszczędzanie baterii jest włączone."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Ładowanie przy użyciu złącza USB nie jest obsługiwane.\nNależy używać tylko dołączonej ładowarki."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Użycie baterii"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Ładowanie przez USB nie jest obsługiwane."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Używaj tylko ładowarki dostarczonej z urządzeniem."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Ustawienia"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Włączyć oszczędzanie baterii?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Włącz"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Włącz oszczędzanie baterii"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Funkcja oszczędzania baterii zmniejszy szybkość działania urządzenia, by ograniczyć wykorzystanie energii.\n\nOszczędzanie baterii wyłączy się, kiedy urządzenie będzie podłączone do źródła zasilania."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ustawienia"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Tryb samolotowy"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Przez godzinę"</item>
     <item quantity="other" msgid="5408537517529822157">"Przez %d godz."</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Oszczędzanie baterii jest włączone"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Urządzenie działa z ograniczoną szybkością."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otwórz ustawienia oszczędzania baterii"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 560f64a..d576ebb 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em curso"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Ligar carregador"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está a ficar fraca."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Bateria fraca"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> restantes. A Poupança de bateria está ligada."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Carregamento USB não suportado. \nUtilize apenas o carregador fornecido."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Utilização da bateria"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"O carregamento por USB não é suportado."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Utilize apenas o carregador fornecido."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Definições"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Iniciar a poupança de bateria?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar a poupança de bateria"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ajudar a aumentar a duração da bateria, a Poupança de bateria reduzirá o desempenho do seu dispositivo.\n\nA Poupança de bateria será desativada assim que o dispositivo for ligado à corrente elétrica."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Definições"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo de avião"</string>
@@ -188,8 +194,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brilho"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Rotação automática"</string>
     <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotação bloqueada"</string>
-    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Vertical"</string>
-    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Horizontal"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Retrato"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Durante uma hora"</item>
     <item quantity="other" msgid="5408537517529822157">"Durante %d horas"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"A poupança de bateria está ligada"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"O desempenho do dispositivo é reduzido."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir as definições de poupança de bateria"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 9dcb25da..caffae9 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em andamento"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Conecte o carregador"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está ficando baixa."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Bateria fraca"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> restante(s). A Economia de bateria está ativada."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"O carregamento via USB não é suportado.\nUse apenas o carregador fornecido."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Uso da bateria"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"O carregamento via USB não é suportado."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Use apenas o carregador fornecido."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Configurações"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Iniciar a economia de bateria?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Iniciar"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Iniciar economia de bateria"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Para ajudar a melhorar a vida útil da bateria, a Economia de bateria reduzirá o desempenho do dispositivo.\n\nA Economia de bateria será desativada quando o dispositivo estiver carregando."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configurações"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Modo avião"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Por 1 hora"</item>
     <item quantity="other" msgid="5408537517529822157">"Por %d horas"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"A Economia de bateria está ativada"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"O desempenho do dispositivo foi reduzido."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Abrir configurações de economia de bateria"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 73c0cd2..0a5a698 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -35,15 +35,28 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nagins avis"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actual"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Avis"</string>
-    <!-- no translation found for battery_low_title (2783104807551211639) -->
-    <skip />
-    <!-- no translation found for battery_low_subtitle (1752040062087829196) -->
+    <!-- no translation found for battery_low_title (6456385927409742437) -->
     <skip />
     <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
     <skip />
+    <!-- no translation found for battery_low_percent_format_saver_started (6534746636002666456) -->
+    <skip />
     <!-- no translation found for invalid_charger (4549105996740522523) -->
     <skip />
-    <string name="battery_low_why" msgid="7279169609518386372">"Consum dad accu"</string>
+    <!-- no translation found for invalid_charger_title (3515740382572798460) -->
+    <skip />
+    <!-- no translation found for invalid_charger_text (5474997287953892710) -->
+    <skip />
+    <!-- no translation found for battery_low_why (4553600287639198111) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_title (5987726159603849352) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_ok (7283108887345688413) -->
+    <skip />
+    <!-- no translation found for battery_saver_start_action (7245333922937402896) -->
+    <skip />
+    <!-- no translation found for battery_saver_confirmation_text (8417584516834617662) -->
+    <skip />
     <!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
     <skip />
     <!-- no translation found for status_bar_settings_wifi_button (1733928151698311923) -->
@@ -434,4 +447,10 @@
     <!-- no translation found for zen_mode_duration_minutes:other (6924190729213550991) -->
     <!-- no translation found for zen_mode_duration_hours:one (3480040795582254384) -->
     <!-- no translation found for zen_mode_duration_hours:other (5408537517529822157) -->
+    <!-- no translation found for battery_saver_notification_title (237918726750955859) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_text (7796554871101546872) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_action_text (7546297220816993504) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 6f992e4..8d5fddc 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nicio notificare"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"În desfăşurare"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificări"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Conectaţi încărcătorul"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria este descărcată."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Bateria este aproape descărcată"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Rămas: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Procent rămas din baterie: <xliff:g id="NUMBER">%d%%</xliff:g>. Economisirea bateriei este activată."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Încărcarea USB nu este acceptată. \nUtilizaţi numai încărcătorul furnizat."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Utilizarea bateriei"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Încărcarea prin USB nu este acceptată."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Utilizați numai încărcătorul furnizat."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Setări"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Porniți economisirea bateriei?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Începeți"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Porniți economisirea bateriei"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pentru a mări autonomia bateriei, funcția Economisirea bateriei reduce performanța dispozitivului.\n\nEconomisirea bateriei se dezactivează când dispozitivul este conectat la priză."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setări"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mod Avion"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Timp de o oră"</item>
     <item quantity="other" msgid="5408537517529822157">"Timp de %d (de) ore"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Economisirea bateriei este activată"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Performanța dispozitivului s-a redus."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Deschideți setările pentru economisirea bateriei"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 12232c5..e940893 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Батарея почти разряжена"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Уровень заряда батареи: <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="invalid_charger_title" msgid="3515740382572798460">"Зарядка через USB не поддерживается."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Используйте только зарядное устройство, поставляемое в комплекте с устройством."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Настройки"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Включить режим энергосбережения?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"ОК"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Включить режим энергосбережения"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Для экономии заряда батареи производительность устройства будет снижена.\n\nКогда устройство заряжается, режим энергосбережения отключен."</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>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"1 ч."</item>
     <item quantity="other" msgid="5408537517529822157">"%d ч."</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Включен режим энергосбережения"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Производительность устройства снижена."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Открыть настройки режима энергосбережения"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index e5e0802..e917350 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žiadne upozornenia"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Prebiehajúce"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Upozornenia"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Pripojte nabíjačku"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Batéria je skoro vybitá."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Batéria je takmer vybitá"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Zostáva: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Zostáva: <xliff:g id="NUMBER">%d%%</xliff:g>. Šetrič batérie je zapnutý."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Nabíjanie pomocou rozhrania USB nie je podporované.\nPoužívajte iba nabíjačku, ktorá bola dodaná spolu so zariadením."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Využitie batérie"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Nabíjanie prostredníctvom USB nie je podporované."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Používajte iba originálnu nabíjačku."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Nastavenia"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Chcete spustiť šetrič batérie?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Spustiť"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Spustiť šetrič batérie"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Šetrič batérie zníži výkonnosť vášho zariadenia, aby tak predĺžil výdrž batérie.\n\nPo pripojení zariadenia do zásuvky sa šetrič batérie deaktivuje."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavenia"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Režim V lietadle"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"Na jednu hodinu"</item>
     <item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Šetrič batérie je zapnutý"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Výkonnosť zariadenia sa znížila."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Otvorte nastavenia šetriča batérie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8fbd70d..0b117a1 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ni obvestil"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Trenutno"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Obvestila"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Priključite polnilnik"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterija je skoraj prazna."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Akumulator je skoraj izpraznjen"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> preostalo"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Še <xliff:g id="NUMBER">%d%%</xliff:g>. Varčevanje z energijo akumulatorja je vklopljeno."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Polnjenje po povezavi USB ni podprto.\nUporabite priloženi polnilnik."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Uporaba baterije"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Polnjenje prek USB-ja ni podprto."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Uporabljajte samo priloženi polnilnik."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Nastavitve"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Želite zagnati varčevanje z energijo akumulatorja?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Začni"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Zaženi varčevanje z energijo akumulatorja"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Zaradi podaljšanja delovanja akumulatorja funkcija Varčevanje z energijo akumulatorja zmanjša zmogljivost delovanja naprave.\n\nVarčevanje z energijo akumulatorja se onemogoči, ko je naprava priklopljena na zunanje napajanje."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavitve"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Način za letalo"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Za eno uro"</item>
     <item quantity="other" msgid="5408537517529822157">"Za %d h"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Varčevanje z energijo akumulatorja je vklopljeno"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Zmogljivost delovanja naprave je zmanjšana."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Odpri nastavitve varčevanja z energijo akumulatorja"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index db8e278..4a49a7b 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Ниво напуњености батерије је низак"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"преостало је <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Преостало је још <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="invalid_charger_title" msgid="3515740382572798460">"Пуњење преко USB-а није подржано."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Користите само пуњач који сте добили."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Подешавања"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Желите ли да покренете Штедњу батерије?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Покрени"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Покрените Штедњу батерије"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Да би продужила век трајања батерије, Штедња батерије умањује перформансе уређаја.\n\nШтедња батерије ће се искључити када прикључите уређај на напајање."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Један сат"</item>
     <item quantity="other" msgid="5408537517529822157">"%d с"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Штедња батерије је укључена"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Перформансе уређаја су умањене."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Отворите подешавања Штедње батерије"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index f92a4f7..d2024c4 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Inga aviseringar"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Pågående"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelanden"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Anslut laddaren"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet håller på att ta slut."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Lågt batteri"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> återstår"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> kvar. Batterisparläget har aktiverats."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Det går inte att ladda via USB.\nAnvänd endast den laddare som levererades med telefonen."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Batteriförbrukning"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Det finns inget stöd för laddning via USB."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Använd endast den medföljande laddaren."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Inställningar"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Vill du aktivera batterisparläget?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Börja"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Aktivera batterisparläget"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Med batterisparläget minskas enhetens prestanda i syfte att förlänga batteritiden.\n\nBatterisparläget inaktiveras när enheten ansluts till ett uttag."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Inställningar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Flygplansläge"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"I en timme"</item>
     <item quantity="other" msgid="5408537517529822157">"I %d timmar"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Batterisparläget har aktiverats"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Enhetens prestanda har minskats."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Öppna inställningarna för batterisparläget"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 24cd574..d42077f 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -30,11 +30,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Hakuna arifa"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Inaendelea"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Arifa"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Unganisha chaja"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Betri inaisha."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Betri imeisha"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> zimebakia"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Imesalia <xliff:g id="NUMBER">%d%%</xliff:g>. Kiokoa betri kimewashwa."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Chaji ya USB haihamiliwi.\n Tumia chaka iliyopeanwa."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Utumiaji wa betri"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Kuchaji kwa kutumia USB hakutumiki."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Tumia chaja iliyonunuliwa pamoja na kifaa pekee."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Mipangilio"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Ungependa kuwasha kiokoa betri?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Anza"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Washa kiokoa betri"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Ili kusaidia kuboresha muda wa matumizi ya betri, Kiokoa betri kitapunguza utendaji wa kifaa chako.\n\nKiokoa betri kitazimwa kifaa chako kitakapochomekwa kwenye nishati ya umeme."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Mipangilio"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Mtandao-Hewa"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Hali ya Ndege"</string>
@@ -239,4 +245,7 @@
     <item quantity="one" msgid="3480040795582254384">"Kwa saa moja"</item>
     <item quantity="other" msgid="5408537517529822157">"Kwa saa %d"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Kiokoa betri kimewashwa"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Utendaji wa kifaa umepunguzwa."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Fungua mipangilio ya hali inayookoa betri"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/config.xml b/packages/SystemUI/res/values-sw600dp-land/config.xml
new file mode 100644
index 0000000..f9b01c8
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp-land/config.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
+  -->
+<resources>
+    <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
+         card. -->
+    <integer name="keyguard_max_notification_count">3</integer>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 326f602..5367fbc 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -23,5 +23,8 @@
     <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.25</item>
 
     <fraction name="keyguard_clock_y_fraction_max">37%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">14%</fraction>
+    <fraction name="keyguard_clock_y_fraction_min">20%</fraction>
+
+    <dimen name="keyguard_clock_notifications_margin_min">36dp</dimen>
+    <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 6dea81f..47581a9 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -28,4 +28,8 @@
 
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
+
+    <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
+         card. -->
+    <integer name="keyguard_max_notification_count">5</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 313e2e8..a5e3924 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -16,8 +16,8 @@
 */
 -->
 <resources>
-    <!-- The width of the notification panel window: 446 + 16 + 16 (padding in the bg drawable) -->
-    <dimen name="notification_panel_width">478dp</dimen>
+    <!-- The width of the notification panel window: 400 + 16 + 16 (padding in the bg drawable) -->
+    <dimen name="notification_panel_width">432dp</dimen>
 
     <!-- Gravity for the notification panel -->
     <!-- 0x31 = top|center_horizontal -->
@@ -56,10 +56,10 @@
          max value is used when no notifications are displaying, and the min value is when the
          highest possible number of notifications are showing. -->
     <fraction name="keyguard_clock_y_fraction_max">34%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">25%</fraction>
+    <fraction name="keyguard_clock_y_fraction_min">24%</fraction>
 
     <!-- The margin between the clock and the notifications on Keyguard. See
          keyguard_clock_height_fraction_* for the difference between min and max.-->
-    <dimen name="keyguard_clock_notifications_margin_min">36dp</dimen>
-    <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen>
+    <dimen name="keyguard_clock_notifications_margin_min">44dp</dimen>
+    <dimen name="keyguard_clock_notifications_margin_max">44dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 0d6bb5c..ee4ba0e3 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"แบตเตอรี่เหลือน้อย"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"เหลืออีก <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"แบตเตอรี่เหลือ <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="invalid_charger_title" msgid="3515740382572798460">"ไม่รองรับการชาร์จผ่าน USB"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"ใช้เฉพาะที่ชาร์จที่ให้มา"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"การตั้งค่า"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"เริ่มใช้โหมดประหยัดแบตเตอรี่ใช่ไหม"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"เริ่ม"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"เริ่มโหมดประหยัดแบตเตอรี่"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"เพื่อช่วยให้ใช้งานแบตเตอรี่ได้ยาวนานขึ้น โหมดประหยัดแบตเตอรี่จะลดประสิทธิภาพการทำงานของอุปกรณ์ลง\n\nโหมดประหยัดแบตเตอรี่จะปิดเมื่อคุณเสียบปลั๊กไฟกับอุปกรณ์"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"การตั้งค่า"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WiFi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"โหมดใช้งานบนเครื่องบิน"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"1 ชั่วโมง"</item>
     <item quantity="other" msgid="5408537517529822157">"%d ชั่วโมง"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"เปิดโหมดประหยัดแบตเตอรี่อยู่"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"ประสิทธิภาพการทำงานของอุปกรณ์ลดลง"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"เปิดการตั้งค่าโหมดประหยัดแบตเตอรี่"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index a76eb5f..42e168e 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Walang mga notification"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Nagpapatuloy"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Mga Notification"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Ikabit ang charger"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Humihina na ang baterya."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Mahina na ang baterya"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> natitira"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> ang natitira. Naka-on ang tagatipid ng baterya."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Hindi sinusuportahan ang pag-charge sa USB.\nGamitin lang ang ibinigay na charger."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Paggamit ng baterya"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Hindi sinusuportahan ang pagtsa-charge gamit ang USB."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Gamitin lang ang ibinigay na charger."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Mga Setting"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Simulan ang tagatipid ng baterya?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Magsimula"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Simulan ang tagatipid ng baterya"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Upang makatulong na patagalin ang baterya, babawasan ng Tagatipid ng baterya ang pagganap ng iyong device.\n\nIdi-disable ang tagatipid ng baterya kapag naka-plug in ang iyong device."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Mga Setting"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Airplane mode"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Sa loob ng isang oras"</item>
     <item quantity="other" msgid="5408537517529822157">"Sa loob ng %d (na) oras"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Naka-on ang tagatipid ng baterya"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Binawasan ang pagganap ng device."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Buksan ang mga setting ng tagatipid ng baterya"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 8b37f15..2967731 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildirim yok"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sürüyor"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Bildirimler"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Şarj cihazını takın"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Pil azalıyor."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Pil gücü düşük"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> kaldı"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> kaldı. Pil tasarrufu açık."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"USB üzerinden şarj desteklenmiyor.\nYalnızca ürünle birlikte verilen şarj cihazını kullanın."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Pil kullanımı"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB şarjı desteklenmiyor."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Yalnızca ürünle birlikte verilen şarj cihazını kullanın."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Ayarlar"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Pil tasarrufu başlatılsın mı?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Başlat"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Pil tasarrufunu başlat"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Pil tasarrufu, pil ömrünü iyileştirmeye yardımcı olmak için cihazınızın performansını düşürür.\n\nCihazınız fişe takıldığında Pil tasarrufu devre dışı bırakılır."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ayarlar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Kablosuz"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Uçak modu"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Bir saat süreyle"</item>
     <item quantity="other" msgid="5408537517529822157">"%d saat süreyle"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Pil tasarrufu açık"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Cihazın performansı düşürüldü."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Pil tasarrufu ayarlarını aç"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2d3609f..43d4146f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"Низький рівень заряду акумулятора"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Залишилося <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Залишилося <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="invalid_charger_title" msgid="3515740382572798460">"Заряджання через USB не підтримується."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Використовуйте лише зарядний пристрій, який постачається в комплекті."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Налаштування"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Увімкнути режим заощадження заряду акумулятора?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Почати"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Увімкнути режим заощадження заряду акумулятора"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Щоб подовжити роботу акумулятора, буде знижено продуктивність пристрою.\n\nРежим заощадження заряду акумулятора вимкнеться, коли пристрій буде підключено до мережі живлення."</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>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Протягом години"</item>
     <item quantity="other" msgid="5408537517529822157">"Протягом %d год"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Режим заощадження заряду акумулятора ввімкнено"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Продуктивність пристрою знижено."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Відкрийте налаштування режиму заощадження заряду акумулятора"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index e15b1b5..eede966 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Không có thông báo nào"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Đang diễn ra"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Thông báo"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Cắm bộ sạc"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Pin đang yếu."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Pin yếu"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> còn lại"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"Còn lại <xliff:g id="NUMBER">%d%%</xliff:g>. Trình tiết kiệm pin đang bật."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Không hỗ trợ sạc qua USB.\nChỉ sử dụng bộ sạc được cung cấp."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Sử dụng pin"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Sạc qua USB không được hỗ trợ."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Chỉ sử dụng bộ sạc được cung cấp."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Cài đặt"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Khởi động trình tiết kiệm pin?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Bắt đầu"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Khởi động trình tiết kiệm pin"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Để giúp tăng tuổi thọ pin, trình tiết kiệm pin sẽ giảm hiệu suất của thiết bị.\n\nTrình tiết kiệm pin sẽ tắt khi thiết bị của bạn được cắm vào nguồn điện."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Cài đặt"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Chế độ trên máy bay"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Trong một giờ"</item>
     <item quantity="other" msgid="5408537517529822157">"Trong %d giờ"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Trình tiết kiệm pin đang bật"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Hiệu suất của thiết bị đã giảm."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Mở cài đặt trình tiết kiệm pin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 2bcd6b8..61d59ab 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"电池电量偏低"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"还剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"电量还剩<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="invalid_charger_title" msgid="3515740382572798460">"不支持USB充电。"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"仅限使用设备随附的充电器。"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"设置"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"要开启节电助手吗?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"开启"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"开启节电助手"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"为了延长电池的续航时间,节电助手会减降设备的性能。\n\n设备接通电源后,节电助手会自动关闭。"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"设置"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"飞行模式"</string>
@@ -189,7 +195,7 @@
     <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="7305323031808150099">"自动旋转"</string>
-    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"旋转功能已锁定"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"屏幕方向:锁定"</string>
     <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"纵向"</string>
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"横向"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"输入法"</string>
@@ -227,7 +233,7 @@
   </plurals>
     <string name="zen_mode_notification_text" msgid="8336623711388065713">"触摸即可显示"</string>
     <string name="zen_mode_title" msgid="8793432092004749188">"勿扰"</string>
-    <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+另外<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>条"</string>
+    <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"再次点按即可打开"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"向上滑动即可解锁"</string>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"1小时"</item>
     <item quantity="other" msgid="5408537517529822157">"%d小时"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"节电助手已开启"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"设备性能已减降。"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"打开节电助手设置"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 25d9bce..8843363 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"電量低"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"剩餘 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"電量剩下 <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="invalid_charger_title" msgid="3515740382572798460">"不支援 USB 充電功能。"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"僅限使用裝置隨附的充電器。"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"設定"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"啟動節約電池用量模式?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"開始"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"啟動節約電池用量模式"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"節約電池用量模式有助於延長電池壽命,但會降低裝置的效能。\n\n裝置接上電源時,節約電池用量模式會自動停用。"</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>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"1 小時"</item>
     <item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"節約電池用量模式已啟用"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"裝置效能已降低。"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"開啟節約電池用量設定"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 4e4007a..a6efe21 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -32,11 +32,17 @@
     <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_title" msgid="6456385927409742437">"電池電力不足"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"還剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"電力剩下 <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="invalid_charger_title" msgid="3515740382572798460">"不支援 USB 充電功能。"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"僅限使用裝置隨附的充電器。"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"設定"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"啟動節約耗電量模式?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"啟動"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"啟動節約耗電量模式"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"節約耗電量模式有助於延長電池續航力,但會讓裝置的效能降低。\n\n裝置接上電源時,節約耗電量模式會自動停用。"</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>
@@ -243,4 +249,7 @@
     <item quantity="one" msgid="3480040795582254384">"1 小時"</item>
     <item quantity="other" msgid="5408537517529822157">"%d 小時"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"節約耗電量模式已啟用"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"裝置效能已降低。"</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"開啟節約耗電量設定"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 7f292c1..bfeb47a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -32,11 +32,17 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Azikho izaziso"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Okuqhubekayo"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Izaziso"</string>
-    <string name="battery_low_title" msgid="2783104807551211639">"Xhuma ishaja."</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Ibhetri iya ngokuphela."</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Ibhethri liphansi"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> okusele"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6534746636002666456">"<xliff:g id="NUMBER">%d%%</xliff:g> esele. Isilondolozi Sebhethri sivuliwe."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Ukushaja i-USB akusekelwe.\nSebenzisa kuphela ishaja enikeziwe."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Ukusebenzisa ibhetri"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Ukushaja kwe-USB akusekelwe."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Sebenzisa kuphela ishaja enikeziwe."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Izilungiselelo"</string>
+    <string name="battery_saver_confirmation_title" msgid="5987726159603849352">"Qala isilondolozi sebhethri?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7283108887345688413">"Qala"</string>
+    <string name="battery_saver_start_action" msgid="7245333922937402896">"Qala isilondolozi sebhethri"</string>
+    <string name="battery_saver_confirmation_text" msgid="8417584516834617662">"Ukusiza ukuthuthukisa impilo yebhethri, Isilondolozi Sebhethri sizonciphisa ukusebenza kwedivayisi yakho.\n\nIsilondolozi Sebhethri sizokhutshazwa uma idivayisi yakho ixhunywa."</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Izilungiselelo"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"I-Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Imodi yendiza"</string>
@@ -241,4 +247,7 @@
     <item quantity="one" msgid="3480040795582254384">"Ihora elilodwa"</item>
     <item quantity="other" msgid="5408537517529822157">"Amahora angu-%d"</item>
   </plurals>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Isilondolozi sebhethri sivuliwe"</string>
+    <string name="battery_saver_notification_text" msgid="7796554871101546872">"Ukusebenza kwedivayisi kwehlisiwe."</string>
+    <string name="battery_saver_notification_action_text" msgid="7546297220816993504">"Vula izilungiselelo zesilondolozi sebhethri"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index 1ce4983..6628f3b 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -42,13 +42,11 @@
 
     <!-- BatteryMeterView parameters -->
     <array name="batterymeter_color_levels">
-        <item>4</item>
         <item>15</item>
         <item>100</item>
     </array>
     <array name="batterymeter_color_values">
         <item>#FFFF3300</item>
-        <item>#FFFF3300</item>
         <item>#FFFFFFFF</item>
     </array>
     <array name="batterymeter_bolt_points">
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index bb6f1a9..8c1a9c7 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -45,18 +45,6 @@
     <!-- Tint color for the content on the notification overflow card. -->
     <color name="keyguard_overflow_content_color">#ff686868</color>
 
-    <!-- The color of the red speed bump dot -->
-    <color name="speed_bump_dot_red">#ffd50000</color>
-
-    <!-- The color of the blue speed bump dot -->
-    <color name="speed_bump_dot_blue">#ff2962ff</color>
-
-    <!-- The color of the yellow speed bump dot -->
-    <color name="speed_bump_dot_yellow">#ffffd600</color>
-
-    <!-- The color of the green speed bump dot -->
-    <color name="speed_bump_dot_green">#ff00c853</color>
-
     <!-- The default recents task bar background color. -->
     <color name="recents_task_bar_default_background_color">#e6444444</color>
     <!-- The default recents task bar text color. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 35bc7e3..4a15363 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -275,14 +275,8 @@
     <!-- The minimum amount of top overscroll to go to the quick settings. -->
     <dimen name="min_top_overscroll_to_qs">36dp</dimen>
 
-    <!-- The height of the collapsed speed bump view. -->
-    <dimen name="speed_bump_height_collapsed">24dp</dimen>
-
-    <!-- The padding inset the explanation text needs compared to the collapsed height -->
-    <dimen name="speed_bump_text_padding_inset">10dp</dimen>
-
-    <!-- The height of the speed bump dots. -->
-    <dimen name="speed_bump_dots_height">5dp</dimen>
+    <!-- The height of the speed bump view. -->
+    <dimen name="speed_bump_height">16dp</dimen>
 
     <!-- The total height of the stack in its collapsed size (i.e. when quick settings is open) -->
     <dimen name="collapsed_stack_height">94dp</dimen>
@@ -301,12 +295,12 @@
     <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
          max value is used when no notifications are displaying, and the min value is when the
          highest possible number of notifications are showing. -->
-    <fraction name="keyguard_clock_y_fraction_max">29.5%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">18%</fraction>
+    <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction>
+    <fraction name="keyguard_clock_y_fraction_min">19.8%</fraction>
 
     <!-- The margin between the clock and the notifications on Keyguard. See
          keyguard_clock_height_fraction_* for the difference between min and max.-->
-    <dimen name="keyguard_clock_notifications_margin_min">22dp</dimen>
+    <dimen name="keyguard_clock_notifications_margin_min">24dp</dimen>
     <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen>
     <dimen name="heads_up_window_height">250dp</dimen>
 
@@ -338,4 +332,7 @@
     <!-- The width of the region on the left/right edge of the screen for performing the camera/
          phone hints. -->
     <dimen name="edge_tap_area_width">48dp</dimen>
+
+    <!-- end margin for multi user switch in expanded quick settings -->
+    <dimen name="multi_user_switch_expanded_margin">8dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index de297e5..260f59c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -59,25 +59,43 @@
     <string name="status_bar_latest_events_title">Notifications</string>
 
     <!-- When the battery is low, this is displayed to the user in a dialog.  The title of the low battery alert.  [CHAR LIMIT=NONE]-->
-    <string name="battery_low_title">Connect charger</string>
-
-    <!-- When the battery is low, this is displayed to the user in a dialog. The subtitle of the low battery alert. [CHAR LIMIT=NONE] -->
-    <string name="battery_low_subtitle">The battery is getting low.</string>
+    <string name="battery_low_title">Battery is low</string>
 
     <!-- A message that appears when the battery level is getting low in a dialog.  This is
         appened to the subtitle of the low battery alert.  "number" is the percentage of battery
         remaining [CHAR LIMIT=none]-->
     <string name="battery_low_percent_format"><xliff:g id="number">%d%%</xliff:g> remaining</string>
 
+    <!-- Same as battery_low_percent_format, with a notice about battery saver if on. [CHAR LIMIT=none]-->
+    <string name="battery_low_percent_format_saver_started"><xliff:g id="number">%d%%</xliff:g> remaining. Battery saver is on.</string>
+
     <!-- A message that appears when a USB charger is plugged in and the device does not
     support charging on it.  That is, a charger that fits into the USB port and goes into
     a wall socket, not into a computer. (This happens because some devices require more
     current than the USB spec allows.  [CHAR LIMIT=NONE] -->
     <string name="invalid_charger">USB charging not supported.\nUse only the supplied charger.</string>
 
+    <!-- First line of invalid_charger, used in the notification form.  [CHAR LIMIT=NONE]-->
+    <string name="invalid_charger_title">USB charging not supported.</string>
+
+    <!-- Second line of invalid_charger, used in the notification form.  [CHAR LIMIT=NONE]-->
+    <string name="invalid_charger_text">Use only the supplied charger.</string>
+
     <!-- When the battery is low, this is the label of the button to go to the
          power usage activity to find out what drained the battery.  [CHAR LIMIT=30] -->
-    <string name="battery_low_why">Battery use</string>
+    <string name="battery_low_why">Settings</string>
+
+    <!-- Battery saver confirmation dialog title [CHAR LIMIT=NONE]-->
+    <string name="battery_saver_confirmation_title">Start battery saver?</string>
+
+    <!-- Battery saver confirmation dialog ok text [CHAR LIMIT=40]-->
+    <string name="battery_saver_confirmation_ok">Start</string>
+
+    <!-- Battery saver notification action [CHAR LIMIT=NONE]-->
+    <string name="battery_saver_start_action">Start battery saver</string>
+
+    <!-- Battery saver confirmation dialog text [CHAR LIMIT=NONE]-->
+    <string name="battery_saver_confirmation_text">To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in.</string>
 
     <!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
     <string name="status_bar_settings_settings_button">Settings</string>
@@ -595,4 +613,13 @@
         <item quantity="one">For one hour</item>
         <item quantity="other">For %d hours</item>
     </plurals>
+
+    <!-- Battery saver notification title. [CHAR LIMIT=60]-->
+    <string name="battery_saver_notification_title">Battery saver is on</string>
+
+    <!-- Battery saver notification text. [CHAR LIMIT=60] -->
+    <string name="battery_saver_notification_text">Device performance is reduced.</string>
+
+    <!-- Battery saver notification action text. [CHAR LIMIT=60] -->
+    <string name="battery_saver_notification_action_text">Open battery saver settings</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b0b018d..79a13f8 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -63,7 +63,7 @@
     <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
         <!-- Note: must be dp to fit in status bar -->
         <item name="android:textSize">16dp</item>
-        <item name="android:textStyle">normal</item>
+        <item name="android:fontFamily">sans-serif-medium</item>
         <item name="android:textColor">@color/status_bar_clock_color</item>
     </style>
 
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 19d06be..5e48258 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -25,8 +25,6 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.os.BatteryManager;
@@ -44,7 +42,6 @@
     private static final boolean SHOW_100_PERCENT = false;
 
     private static final int FULL = 96;
-    private static final int EMPTY = 4;
 
     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
@@ -58,6 +55,7 @@
     private int mHeight;
     private int mWidth;
     private String mWarningString;
+    private final int mCriticalLevel;
     private final int mChargeColor;
     private final float[] mBoltPoints;
     private final Path mBoltPath = new Path();
@@ -197,6 +195,8 @@
         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);
+        mCriticalLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_criticalBatteryWarningLevel);
 
         mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
         mFramePaint.setColor(frameColor);
@@ -303,7 +303,7 @@
 
         if (level >= FULL) {
             drawFrac = 1f;
-        } else if (level <= EMPTY) {
+        } else if (level <= mCriticalLevel) {
             drawFrac = 0f;
         }
 
@@ -360,7 +360,7 @@
         boolean pctOpaque = false;
         float pctX = 0, pctY = 0;
         String pctText = null;
-        if (!tracker.plugged && level > EMPTY && mShowPercent
+        if (!tracker.plugged && level > mCriticalLevel && mShowPercent
                 && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
             mTextPaint.setColor(getColorForLevel(level));
             mTextPaint.setTextSize(height *
@@ -390,7 +390,7 @@
         c.drawPath(mShapePath, mBatteryPaint);
 
         if (!tracker.plugged) {
-            if (level <= EMPTY) {
+            if (level <= mCriticalLevel) {
                 // draw the warning text
                 final float x = mWidth * 0.5f;
                 final float y = (mHeight + mWarningTextHeight) * 0.48f;
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
index feec87c..2943494 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.power;
 
+import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -25,13 +26,13 @@
 import android.media.Ringtone;
 import android.media.RingtoneManager;
 import android.net.Uri;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
-import android.view.View;
+import android.view.ContextThemeWrapper;
 import android.view.WindowManager;
-import android.widget.TextView;
 
 import com.android.systemui.R;
 
@@ -46,13 +47,14 @@
     private int mBatteryLevel;
     private int mBucket;
     private long mScreenOffTime;
+    private boolean mSaver;
+    private int mSaverTriggerLevel;
 
     private AlertDialog mInvalidChargerDialog;
     private AlertDialog mLowBatteryDialog;
-    private TextView mBatteryLevelTextView;
 
     public PowerDialogWarnings(Context context) {
-        mContext = context;
+        mContext = new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light);
     }
 
     @Override
@@ -77,7 +79,7 @@
 
     @Override
     public void updateLowBatteryWarning() {
-        if (mBatteryLevelTextView != null) {
+        if (mLowBatteryDialog != null) {
             showLowBatteryWarning(false /*playSound*/);
         }
     }
@@ -93,27 +95,22 @@
     @Override
     public void showLowBatteryWarning(boolean playSound) {
         Slog.i(TAG,
-                ((mBatteryLevelTextView == null) ? "showing" : "updating")
+                ((mLowBatteryDialog == null) ? "showing" : "updating")
                 + " low battery warning: level=" + mBatteryLevel
                 + " [" + mBucket + "]");
 
-        CharSequence levelText = mContext.getString(
-                R.string.battery_low_percent_format, mBatteryLevel);
+        final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
+                : R.string.battery_low_percent_format;
+        final CharSequence levelText = mContext.getString(textRes, mBatteryLevel);
 
-        if (mBatteryLevelTextView != null) {
-            mBatteryLevelTextView.setText(levelText);
+        if (mLowBatteryDialog != null) {
+            mLowBatteryDialog.setMessage(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);
+            b.setCancelable(true);
+            b.setTitle(R.string.battery_low_title);
+            b.setMessage(levelText);
+            b.setPositiveButton(android.R.string.ok, null);
 
             final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -125,6 +122,11 @@
                         new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
+                        try {
+                            ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+                        } catch (RemoteException e) {
+                            // we tried
+                        }
                         mContext.startActivityAsUser(intent, UserHandle.CURRENT);
                         dismissLowBatteryWarning();
                     }
@@ -136,10 +138,9 @@
                     @Override
                     public void onDismiss(DialogInterface dialog) {
                         mLowBatteryDialog = null;
-                        mBatteryLevelTextView = null;
                     }
                 });
-            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
             d.getWindow().getAttributes().privateFlags |=
                     WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
             d.show();
@@ -198,21 +199,32 @@
         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);
+        b.setCancelable(true);
+        b.setTitle(R.string.invalid_charger_title);
+        b.setMessage(R.string.invalid_charger_text);
+        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.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        d.getWindow().getAttributes().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
         d.show();
         mInvalidChargerDialog = d;
     }
+
+    @Override
+    public void showSaverMode(boolean mode) {
+        mSaver = mode;
+    }
+
+    @Override
+    public void setSaverTrigger(int level) {
+        mSaverTriggerLevel = level;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
new file mode 100644
index 0000000..e8f3745
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.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.power;
+
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.R;
+
+import java.io.PrintWriter;
+
+public class PowerNotificationWarnings implements PowerUI.WarningsUI {
+    private static final String TAG = PowerUI.TAG + ".Notification";
+    private static final boolean DEBUG = PowerUI.DEBUG;
+
+    private static final String TAG_NOTIFICATION = "low_battery";
+    private static final int ID_NOTIFICATION = 100;
+    private static final int AUTO_DISMISS_MS = 10000;
+
+    private static final int SHOWING_NOTHING = 0;
+    private static final int SHOWING_WARNING = 1;
+    private static final int SHOWING_SAVER = 2;
+    private static final int SHOWING_INVALID_CHARGER = 3;
+    private static final String[] SHOWING_STRINGS = {
+        "SHOWING_NOTHING",
+        "SHOWING_WARNING",
+        "SHOWING_SAVER",
+        "SHOWING_INVALID_CHARGER",
+    };
+
+    private static final String ACTION_SHOW_FALLBACK_WARNING = "PNW.warningFallback";
+    private static final String ACTION_SHOW_FALLBACK_CHARGER = "PNW.chargerFallback";
+    private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
+    private static final String ACTION_START_SAVER = "PNW.startSaver";
+
+    private final Context mContext;
+    private final Context mLightContext;
+    private final NotificationManager mNoMan;
+    private final Handler mHandler = new Handler();
+    private final PowerDialogWarnings mFallbackDialogs;
+    private final Receiver mReceiver = new Receiver();
+    private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
+    private final Intent mOpenSaverSettings = settings(Settings.ACTION_BATTERY_SAVER_SETTINGS);
+
+    private int mBatteryLevel;
+    private int mBucket;
+    private long mScreenOffTime;
+    private int mShowing;
+
+    private boolean mSaver;
+    private int mSaverTriggerLevel;
+    private boolean mWarning;
+    private boolean mPlaySound;
+    private boolean mInvalidCharger;
+
+    public PowerNotificationWarnings(Context context) {
+        mContext = context;
+        mLightContext = new ContextThemeWrapper(mContext,
+                android.R.style.Theme_DeviceDefault_Light);
+        mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+        mFallbackDialogs = new PowerDialogWarnings(context);
+        mReceiver.init();
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        pw.print("mSaver="); pw.println(mSaver);
+        pw.print("mWarning="); pw.println(mWarning);
+        pw.print("mPlaySound="); pw.println(mPlaySound);
+        pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
+        pw.print("mShowing="); pw.println(SHOWING_STRINGS[mShowing]);
+    }
+
+    @Override
+    public void update(int batteryLevel, int bucket, long screenOffTime) {
+        mBatteryLevel = batteryLevel;
+        mBucket = bucket;
+        mScreenOffTime = screenOffTime;
+        mFallbackDialogs.update(batteryLevel, bucket, screenOffTime);
+    }
+
+    @Override
+    public void showSaverMode(boolean mode) {
+        mSaver = mode;
+        updateNotification();
+    }
+
+    @Override
+    public void setSaverTrigger(int level) {
+        mSaverTriggerLevel = level;
+        updateNotification();
+    }
+
+    private void updateNotification() {
+        Slog.d(TAG, "updateNotification mWarning=" + mWarning
+                + " mSaver=" + mSaver + " mInvalidCharger=" + mInvalidCharger);
+        if (mInvalidCharger) {
+            showInvalidChargerNotification();
+            mShowing = SHOWING_INVALID_CHARGER;
+        } else if (mWarning) {
+            showWarningNotification();
+            mShowing = SHOWING_WARNING;
+        } else if (mSaver) {
+            showSaverNotification();
+            mShowing = SHOWING_SAVER;
+        } else {
+            mNoMan.cancel(TAG_NOTIFICATION, ID_NOTIFICATION);
+            mShowing = SHOWING_NOTHING;
+        }
+    }
+
+    private void showInvalidChargerNotification() {
+        final Notification.Builder nb = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.ic_power_low)
+                .setShowWhen(false)
+                .setOngoing(true)
+                .setContentTitle(mContext.getString(R.string.invalid_charger_title))
+                .setContentText(mContext.getString(R.string.invalid_charger_text))
+                .setPriority(Notification.PRIORITY_MAX)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setFullScreenIntent(pendingBroadcast(ACTION_SHOW_FALLBACK_CHARGER), true);
+        final Notification n = nb.build();
+        if (n.headsUpContentView != null) {
+            n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
+        }
+        mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT);
+    }
+
+    private void showWarningNotification() {
+        final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
+                : R.string.battery_low_percent_format;
+        final Notification.Builder nb = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.ic_power_low)
+                .setShowWhen(false)
+                .setContentTitle(mContext.getString(R.string.battery_low_title))
+                .setContentText(mContext.getString(textRes, mBatteryLevel))
+                .setOngoing(true)
+                .setPriority(Notification.PRIORITY_MAX)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setFullScreenIntent(pendingBroadcast(ACTION_SHOW_FALLBACK_WARNING), true);
+        if (hasBatterySettings()) {
+            nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
+        }
+        if (!mSaver && mSaverTriggerLevel <= 0) {
+            nb.addAction(R.drawable.ic_power_saver,
+                    mContext.getString(R.string.battery_saver_start_action),
+                    pendingBroadcast(ACTION_START_SAVER));
+        }
+        if (mPlaySound) {
+            attachLowBatterySound(nb);
+        }
+        final Notification n = nb.build();
+        if (n.headsUpContentView != null) {
+            n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
+        }
+        mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT);
+    }
+
+    private void showSaverNotification() {
+        final Notification.Builder nb = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.ic_power_saver)
+                .setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
+                .setContentText(mContext.getString(R.string.battery_saver_notification_text))
+                .setOngoing(true)
+                .setShowWhen(false)
+                .setCategory(Notification.CATEGORY_SYSTEM);
+        if (hasSaverSettings()) {
+            nb.addAction(0,
+                    mContext.getString(R.string.battery_saver_notification_action_text),
+                    pendingActivity(mOpenSaverSettings));
+            nb.setContentIntent(pendingActivity(mOpenSaverSettings));
+        }
+        mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, nb.build(), UserHandle.CURRENT);
+    }
+
+    private PendingIntent pendingActivity(Intent intent) {
+        return PendingIntent.getActivityAsUser(mContext,
+                0, intent, 0, null, UserHandle.CURRENT);
+    }
+
+    private PendingIntent pendingBroadcast(String action) {
+        return PendingIntent.getBroadcastAsUser(mContext,
+                0, new Intent(action), 0, UserHandle.CURRENT);
+    }
+
+    private static Intent settings(String action) {
+        return new Intent(action).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                | Intent.FLAG_ACTIVITY_NO_HISTORY
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    }
+
+    @Override
+    public boolean isInvalidChargerWarningShowing() {
+        return mInvalidCharger;
+    }
+
+    @Override
+    public void updateLowBatteryWarning() {
+        updateNotification();
+        mFallbackDialogs.updateLowBatteryWarning();
+    }
+
+    @Override
+    public void dismissLowBatteryWarning() {
+        Slog.i(TAG, "dismissing low battery warning: level=" + mBatteryLevel);
+        dismissLowBatteryNotification();
+        mFallbackDialogs.dismissLowBatteryWarning();
+    }
+
+    private void dismissLowBatteryNotification() {
+        Slog.i(TAG, "dismissing low battery notification");
+        mWarning = false;
+        updateNotification();
+    }
+
+    private boolean hasBatterySettings() {
+        return mOpenBatterySettings.resolveActivity(mContext.getPackageManager()) != null;
+    }
+
+    private boolean hasSaverSettings() {
+        return mOpenSaverSettings.resolveActivity(mContext.getPackageManager()) != null;
+    }
+
+    @Override
+    public void showLowBatteryWarning(boolean playSound) {
+        Slog.i(TAG,
+                "show low battery warning: level=" + mBatteryLevel
+                + " [" + mBucket + "]");
+        mPlaySound = playSound;
+        mWarning = true;
+        updateNotification();
+        mHandler.removeCallbacks(mDismissLowBatteryNotification);
+        mHandler.postDelayed(mDismissLowBatteryNotification, AUTO_DISMISS_MS);
+    }
+
+    private void attachLowBatterySound(Notification.Builder b) {
+        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) {
+                    b.setSound(soundUri, AudioManager.STREAM_SYSTEM);
+                    Slog.d(TAG, "playing sound " + soundUri);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void dismissInvalidChargerWarning() {
+        dismissInvalidChargerNotification();
+        mFallbackDialogs.dismissInvalidChargerWarning();
+    }
+
+    private void dismissInvalidChargerNotification() {
+        Slog.i(TAG, "dismissing invalid charger notification");
+        mInvalidCharger = false;
+        updateNotification();
+    }
+
+    @Override
+    public void showInvalidChargerWarning() {
+        mInvalidCharger = true;
+        updateNotification();
+    }
+
+    private void showStartSaverConfirmation() {
+        final AlertDialog d = new AlertDialog.Builder(mLightContext)
+                .setTitle(R.string.battery_saver_confirmation_title)
+                .setMessage(R.string.battery_saver_confirmation_text)
+                .setNegativeButton(android.R.string.cancel, null)
+                .setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverMode)
+                .create();
+
+        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        d.getWindow().getAttributes().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        d.show();
+    }
+
+    private void setSaverSetting(boolean mode) {
+        final int val = mode ? 1 : 0;
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, val);
+    }
+
+    private final class Receiver extends BroadcastReceiver {
+
+        public void init() {
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(ACTION_SHOW_FALLBACK_WARNING);
+            filter.addAction(ACTION_SHOW_FALLBACK_CHARGER);
+            filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
+            filter.addAction(ACTION_START_SAVER);
+            mContext.registerReceiver(this, filter, null, mHandler);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            Slog.i(TAG, "Received " + action);
+            if (action.equals(ACTION_SHOW_FALLBACK_WARNING)) {
+                dismissLowBatteryNotification();
+                mFallbackDialogs.showLowBatteryWarning(false /*playSound*/);
+            } else if (action.equals(ACTION_SHOW_FALLBACK_CHARGER)) {
+                dismissInvalidChargerNotification();
+                mFallbackDialogs.showInvalidChargerWarning();
+            } else if (action.equals(ACTION_SHOW_BATTERY_SETTINGS)) {
+                dismissLowBatteryNotification();
+                mContext.startActivityAsUser(mOpenBatterySettings, UserHandle.CURRENT);
+            } else if (action.equals(ACTION_START_SAVER)) {
+                dismissLowBatteryNotification();
+                showStartSaverConfirmation();
+            }
+        }
+    }
+
+    private final OnClickListener mStartSaverMode = new OnClickListener() {
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            AsyncTask.execute(new Runnable() {
+                @Override
+                public void run() {
+                    setSaverSetting(true);
+                }
+            });
+        }
+    };
+
+    private final Runnable mDismissLowBatteryNotification = new Runnable() {
+        @Override
+        public void run() {
+            dismissLowBatteryNotification();
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 0fb0f8b..1bb7edb 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -17,13 +17,17 @@
 package com.android.systemui.power;
 
 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.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;
 
@@ -35,13 +39,15 @@
 
 public class PowerUI extends SystemUI {
     static final String TAG = "PowerUI";
-
     static final boolean DEBUG = false;
 
-    private WarningsUI mWarnings;
 
     private final Handler mHandler = new Handler();
+    private final SettingsObserver mObserver = new SettingsObserver(mHandler);
+    private final Receiver mReceiver = new Receiver();
 
+    private PowerManager mPowerManager;
+    private WarningsUI mWarnings;
     private int mBatteryLevel = 100;
     private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
     private int mPlugType = 0;
@@ -53,24 +59,54 @@
     private long mScreenOffTime = -1;
 
     public void start() {
+        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
+        mWarnings = new PowerNotificationWarnings(mContext);
 
-        mLowBatteryAlertCloseLevel = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
-        mLowBatteryReminderLevels[0] = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryWarningLevel);
-        mLowBatteryReminderLevels[1] = mContext.getResources().getInteger(
+        ContentObserver obs = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                updateBatteryWarningLevels();
+            }
+        };
+        final ContentResolver resolver = mContext.getContentResolver();
+        resolver.registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+                false, obs, UserHandle.USER_ALL);
+        updateBatteryWarningLevels();
+        mReceiver.init();
+        mObserver.init();
+    }
+
+    private void setSaverMode(boolean mode) {
+        mWarnings.showSaverMode(mode);
+    }
+
+    private void setSaverTrigger(int level) {
+        mWarnings.setSaverTrigger(level);
+    }
+
+    void updateBatteryWarningLevels() {
+        int critLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
 
-        final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
-        mWarnings = new PowerDialogWarnings(mContext);
+        final ContentResolver resolver = mContext.getContentResolver();
+        int defWarnLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryWarningLevel);
+        int warnLevel = Settings.Global.getInt(resolver,
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
+        if (warnLevel == 0) {
+            warnLevel = defWarnLevel;
+        }
+        if (warnLevel < critLevel) {
+            warnLevel = critLevel;
+        }
 
-        // Register for Intent broadcasts for...
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(Intent.ACTION_SCREEN_ON);
-        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+        mLowBatteryReminderLevels[0] = warnLevel;
+        mLowBatteryReminderLevels[1] = critLevel;
+        mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0]
+                + mContext.getResources().getInteger(
+                        com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
     }
 
     /**
@@ -87,7 +123,7 @@
         if (level >= mLowBatteryAlertCloseLevel) {
             return 1;
         }
-        if (level >= mLowBatteryReminderLevels[0]) {
+        if (level > mLowBatteryReminderLevels[0]) {
             return 0;
         }
         final int N = mLowBatteryReminderLevels.length;
@@ -99,7 +135,23 @@
         throw new RuntimeException("not possible!");
     }
 
-    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+    private final class Receiver extends BroadcastReceiver {
+
+        public void init() {
+            // Register for Intent broadcasts for...
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+            filter.addAction(Intent.ACTION_SCREEN_OFF);
+            filter.addAction(Intent.ACTION_SCREEN_ON);
+            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+            mContext.registerReceiver(this, filter, null, mHandler);
+            updateSaverMode();
+        }
+
+        private void updateSaverMode() {
+            setSaverMode(mPowerManager.isPowerSaveMode());
+        }
+
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -160,6 +212,8 @@
                 mScreenOffTime = SystemClock.elapsedRealtime();
             } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
                 mScreenOffTime = -1;
+            } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
+                updateSaverMode();
             } else {
                 Slog.w(TAG, "unknown intent: " + intent);
             }
@@ -197,6 +251,8 @@
 
     public interface WarningsUI {
         void update(int batteryLevel, int bucket, long screenOffTime);
+        void setSaverTrigger(int level);
+        void showSaverMode(boolean mode);
         void dismissLowBatteryWarning();
         void showLowBatteryWarning(boolean playSound);
         void dismissInvalidChargerWarning();
@@ -205,5 +261,29 @@
         boolean isInvalidChargerWarningShowing();
         void dump(PrintWriter pw);
     }
+
+    private final class SettingsObserver extends ContentObserver {
+        private final Uri LOW_POWER_MODE_TRIGGER_LEVEL_URI =
+                Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL);
+
+        public SettingsObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void init() {
+            onChange(true, LOW_POWER_MODE_TRIGGER_LEVEL_URI);
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.registerContentObserver(LOW_POWER_MODE_TRIGGER_LEVEL_URI, false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (LOW_POWER_MODE_TRIGGER_LEVEL_URI.equals(uri)) {
+                final int level = Settings.Global.getInt(mContext.getContentResolver(),
+                        Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+                setSaverTrigger(level);
+            }
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index c76ee8c..786cd9e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -287,6 +287,7 @@
         public boolean activityIn;
         public boolean activityOut;
         public int overlayIconId;
+        public boolean filter;
 
         @Override
         public boolean copyTo(State other) {
@@ -300,6 +301,7 @@
             o.activityIn = activityIn;
             o.activityOut = activityOut;
             o.overlayIconId = overlayIconId;
+            o.filter = filter;
             return super.copyTo(other) || changed;
         }
 
@@ -311,6 +313,7 @@
             rt.insert(rt.length() - 1, ",activityIn=" + activityIn);
             rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
             rt.insert(rt.length() - 1, ",overlayIconId=" + overlayIconId);
+            rt.insert(rt.length() - 1, ",filter=" + filter);
             return rt;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 901cc10..d5fe033 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -93,12 +93,12 @@
         final SignalState s = (SignalState) state;
         mSignal.setImageDrawable(null);  // force refresh
         mSignal.setImageResource(s.iconId);
-        mSignal.setColorFilter(FILTER);
+        mSignal.setColorFilter(s.filter ? FILTER : null);
         if (s.overlayIconId > 0) {
             mOverlay.setVisibility(VISIBLE);
             mOverlay.setImageDrawable(null);  // force refresh
             mOverlay.setImageResource(s.overlayIconId);
-            mOverlay.setColorFilter(FILTER);
+            mOverlay.setColorFilter(s.filter ? FILTER : null);
         } else {
             mOverlay.setVisibility(GONE);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 182a0ce..6d91d33 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -72,12 +72,15 @@
         if (cb == null) return;
 
         final Resources r = mContext.getResources();
-        state.iconId = cb.enabled && (cb.mobileSignalIconId > 0)
+        state.iconId = cb.noSim
+                ? R.drawable.stat_sys_no_sim
+                : cb.enabled && (cb.mobileSignalIconId > 0)
                 ? cb.mobileSignalIconId
                 : R.drawable.ic_qs_signal_no_signal;
         state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled
                 ? cb.dataTypeIconId
                 : 0;
+        state.filter = state.iconId != R.drawable.stat_sys_no_sim;
         state.activityIn = cb.enabled && cb.activityIn;
         state.activityOut = cb.enabled && cb.activityOut;
 
@@ -117,6 +120,7 @@
         boolean activityIn;
         boolean activityOut;
         String enabledDesc;
+        boolean noSim;
     }
 
     private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() {
@@ -134,7 +138,7 @@
                 int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description) {
+                String dataTypeContentDescriptionId, String description, boolean noSim) {
             final CallbackInfo info = new CallbackInfo();  // TODO pool?
             info.enabled = enabled;
             info.wifiEnabled = mWifiEnabled;
@@ -145,6 +149,7 @@
             info.activityIn = activityIn;
             info.activityOut = activityOut;
             info.enabledDesc = description;
+            info.noSim = noSim;
             refreshState(info);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 5301362..7c2c7c3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -71,6 +71,6 @@
         state.visible = mVisible;
         state.value = enabled;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
-        state.iconId = R.drawable.ic_qs_color_inversion;
+        state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index db9b054..04f1eb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.qs.tiles;
 
-import android.content.res.Resources;
-import android.graphics.drawable.AnimationDrawable;
-
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.LocationController;
@@ -63,28 +60,15 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         final boolean locationEnabled =  mController.isLocationEnabled();
         state.visible = true;
-        if (state.value != locationEnabled) {
-            state.value = locationEnabled;
-            final Resources res = mContext.getResources();
-            final AnimationDrawable d = (AnimationDrawable) res.getDrawable(locationEnabled
-                    ? R.drawable.ic_qs_location_on
-                    : R.drawable.ic_qs_location_off);
-            state.icon = d;
-            mUiHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    d.start();
-                }
-            });
-        }
+        state.value = locationEnabled;
         if (locationEnabled) {
-            if (state.icon == null) state.iconId = R.drawable.ic_qs_location_01;
+            state.iconId = R.drawable.ic_qs_location_on;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location,
                     mContext.getString(R.string.accessibility_desc_on));
         } else {
-            if (state.icon == null) state.iconId = R.drawable.ic_qs_location_11;
+            state.iconId = R.drawable.ic_qs_location_off;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 6b73002..a236497 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -87,6 +87,7 @@
         state.connected = wifiConnected;
         state.activityIn = cb.enabled && cb.activityIn;
         state.activityOut = cb.enabled && cb.activityOut;
+        state.filter = true;
         final String signalContentDescription;
         final Resources r = mContext.getResources();
         if (wifiConnected) {
@@ -159,7 +160,7 @@
                 int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description) {
+                String dataTypeContentDescriptionId, String description, boolean noSim) {
             // noop
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 2f6d58f..24a31f8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -283,7 +283,7 @@
 
     /** Updates each of the task animation rects. */
     void updateAnimationRects() {
-        if (mServiceIsBound && mBootCompleted) {
+        if (mServiceIsBound) {
             Resources res = mContext.getResources();
             int statusBarHeight = res.getDimensionPixelSize(
                     com.android.internal.R.dimen.status_bar_height);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 76e88a5..147ff62 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -106,7 +106,7 @@
             // 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;
+            public static final float StackPeekMinScale = 0.8f;
             // The number of cards we see in the peek space
             public static final int StackPeekNumCards = 3;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 8680786..96344d5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -41,6 +41,8 @@
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.views.RecentsView;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Set;
 
@@ -79,6 +81,19 @@
     boolean mVisible;
     boolean mTaskLaunched;
 
+    private static Method sPropertyMethod;
+    static {
+        try {
+            Class<?> c = Class.forName("android.view.GLES20Canvas");
+            sPropertyMethod = c.getDeclaredMethod("setProperty", String.class, String.class);
+            if (!sPropertyMethod.isAccessible()) sPropertyMethod.setAccessible(true);
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+        }
+    }
+
     // Broadcast receiver to handle messages from our RecentsService
     BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -139,21 +154,12 @@
         // 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);
-
-            // Un-dim the background
-            WindowManager.LayoutParams wlp = getWindow().getAttributes();
-            wlp.dimAmount = 0f;
-            getWindow().setAttributes(wlp);
-            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         }
+
+        // Dim the background
+        mRecentsView.setBackgroundColor(0x80000000);
     }
 
     /** Attempts to allocate and bind the search bar app widget */
@@ -277,6 +283,9 @@
         LayoutInflater inflater = LayoutInflater.from(this);
         mEmptyView = inflater.inflate(R.layout.recents_empty, mContainerView, false);
         mNavBarScrimView = inflater.inflate(R.layout.recents_nav_bar_scrim, mContainerView, false);
+        mNavBarScrimView.setLayoutParams(new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM));
 
         mContainerView = new FrameLayout(this);
         mContainerView.addView(mRecentsView);
@@ -296,6 +305,16 @@
         if (savedInstanceState != null) {
             onConfigurationChange();
         }
+
+        // XXX: Update the shadows
+        try {
+            sPropertyMethod.invoke(null, "ambientShadowStrength", String.valueOf(35f));
+            sPropertyMethod.invoke(null, "ambientRatio", String.valueOf(0.5f));
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        }
     }
 
     void onConfigurationChange() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index 0c2c11d..113efe3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -121,6 +121,7 @@
             // Send a broadcast to hide recents
             Intent intent = new Intent(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY);
             intent.setPackage(context.getPackageName());
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             if (msg.arg1 != 0) {
                 intent.putExtra(RecentsService.EXTRA_TRIGGERED_FROM_ALT_TAB, true);
             }
@@ -129,6 +130,7 @@
             // Send a broadcast to toggle recents
             Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
             intent.setPackage(context.getPackageName());
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             context.sendBroadcast(intent);
 
             // Time this path
@@ -140,6 +142,7 @@
             // Send a broadcast to start the enter animation
             Intent intent = new Intent(RecentsService.ACTION_START_ENTER_ANIMATION);
             intent.setPackage(context.getPackageName());
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             context.sendBroadcast(intent);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 5830e37..8d9f8be 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -156,10 +156,12 @@
         float boundedT = Math.max(t, -(numPeekCards + 1));
 
         // Set the scale relative to its position
+        int numFrontScaledCards = 3;
         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 scaleInc = scaleRange / (numPeekCards + numFrontScaledCards);
+        float scale = Math.max(minScale, Math.min(1f, minScale + 
+            ((boundedT + (numPeekCards + 1)) * scaleInc)));
         float scaleYOffset = ((1f - scale) * mTaskRect.height()) / 2;
         transform.scale = scale;
 
@@ -171,6 +173,12 @@
             transform.translationY = (int) (boundedT * overlapHeight - scaleYOffset);
         }
 
+        // Set the z translation
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        int minZ = config.taskViewTranslationZMinPx;
+        int incZ = config.taskViewTranslationZIncrementPx;
+        transform.translationZ = (int) Math.max(minZ, minZ + ((boundedT + numPeekCards) * incZ));
+
         // Set the alphas
         transform.dismissAlpha = Math.max(-1f, Math.min(0f, t + 1)) + 1f;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 632c816..5df5e4d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -142,8 +142,6 @@
     void updateViewPropertiesToTaskTransform(TaskViewTransform animateFromTransform,
                                              TaskViewTransform toTransform, int duration) {
         RecentsConfiguration config = RecentsConfiguration.getInstance();
-        int minZ = config.taskViewTranslationZMinPx;
-        int incZ = config.taskViewTranslationZIncrementPx;
 
         // Update the bar view
         mBarView.updateViewPropertiesToTaskTransform(animateFromTransform, toTransform, duration);
@@ -153,14 +151,14 @@
             if (animateFromTransform != null) {
                 setTranslationY(animateFromTransform.translationY);
                 if (Constants.DebugFlags.App.EnableShadows) {
-                    setTranslationZ(Math.max(minZ, minZ + (animateFromTransform.t * incZ)));
+                    setTranslationZ(animateFromTransform.translationZ);
                 }
                 setScaleX(animateFromTransform.scale);
                 setScaleY(animateFromTransform.scale);
                 setAlpha(animateFromTransform.alpha);
             }
             if (Constants.DebugFlags.App.EnableShadows) {
-                animate().translationZ(Math.max(minZ, minZ + (toTransform.t * incZ)));
+                animate().translationZ(toTransform.translationZ);
             }
             animate().translationY(toTransform.translationY)
                     .scaleX(toTransform.scale)
@@ -179,7 +177,7 @@
         } else {
             setTranslationY(toTransform.translationY);
             if (Constants.DebugFlags.App.EnableShadows) {
-                setTranslationZ(Math.max(minZ, minZ + (toTransform.t * incZ)));
+                setTranslationZ(toTransform.translationZ);
             }
             setScaleX(toTransform.scale);
             setScaleY(toTransform.scale);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index e6391a8..3c3ebd7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -22,6 +22,7 @@
 /* The transform state for a task view */
 public class TaskViewTransform {
     public int translationY = 0;
+    public int translationZ = 0;
     public float scale = 1f;
     public float alpha = 1f;
     public float dismissAlpha = 1f;
@@ -35,6 +36,7 @@
 
     public TaskViewTransform(TaskViewTransform o) {
         translationY = o.translationY;
+        translationZ = o.translationZ;
         scale = o.scale;
         alpha = o.alpha;
         dismissAlpha = o.dismissAlpha;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index a770f58..80e85f9 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -34,6 +34,7 @@
 
 public class BrightnessController implements ToggleSlider.Listener {
     private static final String TAG = "StatusBar.BrightnessController";
+    private static final boolean SHOW_AUTOMATIC_ICON = false;
 
     /**
      * {@link android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ} uses the range [-1, 1].
@@ -232,7 +233,7 @@
 
     private void updateIcon(boolean automatic) {
         if (mIcon != null) {
-            mIcon.setImageResource(automatic ?
+            mIcon.setImageResource(automatic && SHOW_AUTOMATIC_ICON ?
                     com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
                     com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index b91e129..8d19f50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -158,7 +158,7 @@
     private final Runnable mTapTimeoutRunnable = new Runnable() {
         @Override
         public void run() {
-            makeInactive();
+            makeInactive(true /* animate */);
         }
     };
 
@@ -183,7 +183,7 @@
                 break;
             case MotionEvent.ACTION_MOVE:
                 if (!isWithinTouchSlop(event)) {
-                    makeInactive();
+                    makeInactive(true /* animate */);
                     return false;
                 }
                 break;
@@ -193,14 +193,17 @@
                         makeActive();
                         postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
                     } else {
-                        performClick();
+                        boolean performed = performClick();
+                        if (performed) {
+                            removeCallbacks(mTapTimeoutRunnable);
+                        }
                     }
                 } else {
-                    makeInactive();
+                    makeInactive(true /* animate */);
                 }
                 break;
             case MotionEvent.ACTION_CANCEL:
-                makeInactive();
+                makeInactive(true /* animate */);
                 break;
             default:
                 break;
@@ -257,10 +260,14 @@
     /**
      * Cancels the hotspot and makes the notification inactive.
      */
-    private void makeInactive() {
+    public void makeInactive(boolean animate) {
         if (mActivated) {
             if (mDimmed) {
-                startActivateAnimation(true /* reverse */);
+                if (animate) {
+                    startActivateAnimation(true /* reverse */);
+                } else {
+                    mBackgroundNormal.setVisibility(View.INVISIBLE);
+                }
             }
             mActivated = false;
         }
@@ -351,6 +358,7 @@
             mBackgroundDimmed.setVisibility(View.INVISIBLE);
             mBackgroundNormal.setVisibility(View.VISIBLE);
             mBackgroundNormal.setAlpha(1f);
+            removeCallbacks(mTapTimeoutRunnable);
         }
     }
 
@@ -581,7 +589,7 @@
     }
 
     public interface OnActivatedListener {
-        void onActivated(View view);
-        void onActivationReset(View view);
+        void onActivated(ActivatableNotificationView view);
+        void onActivationReset(ActivatableNotificationView view);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 508c34e..b94493e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -48,7 +48,7 @@
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
 import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.util.Log;
@@ -80,11 +80,10 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
+import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.Locale;
 
 import static com.android.keyguard.KeyguardHostView.OnDismissAction;
@@ -106,6 +105,7 @@
     protected static final int MSG_SHOW_HEADS_UP = 1026;
     protected static final int MSG_HIDE_HEADS_UP = 1027;
     protected static final int MSG_ESCALATE_HEADS_UP = 1028;
+    protected static final int MSG_DECAY_HEADS_UP = 1029;
 
     protected static final boolean ENABLE_HEADS_UP = true;
     // scores above this threshold should be displayed in heads up mode.
@@ -129,8 +129,9 @@
     protected NotificationData mNotificationData = new NotificationData();
     protected NotificationStackScrollLayout mStackScroller;
 
-    protected NotificationData.Entry mInterruptingNotificationEntry;
-    protected long mInterruptingNotificationTime;
+    // for heads up notifications
+    protected HeadsUpNotificationView mHeadsUpNotificationView;
+    protected int mHeadsUpNotificationDecay;
 
     // used to notify status bar for suppressing notification LED
     protected boolean mPanelSlightlyVisible;
@@ -291,7 +292,7 @@
         public void onListenerConnected() {
             if (DEBUG) Log.d(TAG, "onListenerConnected");
             final StatusBarNotification[] notifications = getActiveNotifications();
-            final Ranking currentRanking = getCurrentRanking();
+            final RankingMap currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -303,41 +304,60 @@
         }
 
         @Override
-        public void onNotificationPosted(final StatusBarNotification sbn) {
+        public void onNotificationPosted(final StatusBarNotification sbn,
+                final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
-            final Ranking currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    if (mNotificationData.findByKey(sbn.getKey()) != null) {
-                        updateNotificationInternal(sbn, currentRanking);
+                    Notification n = sbn.getNotification();
+                    boolean isUpdate = mNotificationData.findByKey(sbn.getKey()) != null
+                            || isHeadsUp(sbn.getKey());
+                    boolean isGroupedChild = n.getGroup() != null
+                            && (n.flags & Notification.FLAG_GROUP_SUMMARY) == 0;
+                    if (isGroupedChild) {
+                        if (DEBUG) {
+                            Log.d(TAG, "Ignoring group child: " + sbn);
+                        }
+                        // Don't show grouped notifications. If this is an
+                        // update, i.e. the notification existed before but
+                        // wasn't a group child, remove the old instance.
+                        // Otherwise just update the ranking.
+                        if (isUpdate) {
+                            removeNotificationInternal(sbn.getKey(), rankingMap);
+                        } else {
+                            updateRankingInternal(rankingMap);
+                        }
+                        return;
+                    }
+                    if (isUpdate) {
+                        updateNotificationInternal(sbn, rankingMap);
                     } else {
-                        addNotificationInternal(sbn, currentRanking);
+                        addNotificationInternal(sbn, rankingMap);
                     }
                 }
             });
         }
 
         @Override
-        public void onNotificationRemoved(final StatusBarNotification sbn) {
+        public void onNotificationRemoved(final StatusBarNotification sbn,
+                final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
-            final Ranking currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    removeNotificationInternal(sbn.getKey(), currentRanking);
+                    removeNotificationInternal(sbn.getKey(), rankingMap);
                 }
             });
         }
 
         @Override
-        public void onNotificationRankingUpdate() {
+        public void onNotificationRankingUpdate(final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onRankingUpdate");
-            final Ranking currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    updateRankingInternal(currentRanking);
+                    updateRankingInternal(rankingMap);
                 }
             });
         }
@@ -466,6 +486,10 @@
         // should be overridden
     }
 
+    public boolean isHeadsUp(String key) {
+      return mHeadsUpNotificationView != null && mHeadsUpNotificationView.isShowing(key);
+    }
+
     public boolean notificationIsForCurrentProfiles(StatusBarNotification n) {
         final int thisUserId = mCurrentUserId;
         final int notificationUserId = n.getUserId();
@@ -505,8 +529,8 @@
 
     protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
         View vetoButton = row.findViewById(R.id.veto);
-        if (n.isClearable() || (mInterruptingNotificationEntry != null
-                && mInterruptingNotificationEntry.row == row)) {
+        if (n.isClearable() || (mHeadsUpNotificationView.getEntry() != null
+                && mHeadsUpNotificationView.getEntry().row == row)) {
             final String _pkg = n.getPackageName();
             final String _tag = n.getTag();
             final int _id = n.getId();
@@ -765,6 +789,12 @@
 
     public abstract void resetHeadsUpDecayTimer();
 
+    public abstract void scheduleHeadsUpOpen();
+
+    public abstract void scheduleHeadsUpClose();
+
+    public abstract void scheduleHeadsUpEscalation();
+
     /**
      * Save the current "public" (locked and secure) state of the lockscreen.
      */
@@ -796,6 +826,18 @@
         return mUsersAllowingPrivateNotifications.get(userHandle);
     }
 
+    public void onNotificationClear(StatusBarNotification notification) {
+        try {
+            mBarService.onNotificationClear(
+                    notification.getPackageName(),
+                    notification.getTag(),
+                    notification.getId(),
+                    notification.getUserId());
+        } catch (android.os.RemoteException ex) {
+            // oh well
+        }
+    }
+
     protected class H extends Handler {
         public void handleMessage(Message m) {
             Intent intent;
@@ -873,10 +915,7 @@
     }
 
     public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent, boolean isHeadsUp) {
-        int minHeight =
-                mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
-        int maxHeight =
-                mContext.getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+        int maxHeight = mRowMaxHeight;
         StatusBarNotification sbn = entry.notification;
         RemoteViews contentView = sbn.getNotification().contentView;
         RemoteViews bigContentView = sbn.getNotification().bigContentView;
@@ -1039,7 +1078,7 @@
             }
         }
         entry.row = row;
-        entry.row.setHeightRange(mRowMinHeight, mRowMaxHeight);
+        entry.row.setHeightRange(mRowMinHeight, maxHeight);
         entry.row.setOnActivatedListener(this);
         entry.row.setIsBelowSpeedBump(isBelowSpeedBump(entry.notification));
         entry.expanded = contentViewLocal;
@@ -1101,7 +1140,7 @@
 
                     try {
                         if (mIsHeadsUp) {
-                            mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+                            mHeadsUpNotificationView.clear();
                         }
                         mBarService.onNotificationClick(mNotificationKey);
                     } catch (RemoteException ex) {
@@ -1157,7 +1196,7 @@
         }
     }
 
-    protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) {
+    protected StatusBarNotification removeNotificationViews(String key, RankingMap ranking) {
         NotificationData.Entry entry = mNotificationData.remove(key, ranking);
         if (entry == null) {
             Log.w(TAG, "removeNotification for unknown key: " + key);
@@ -1197,7 +1236,7 @@
         return entry;
     }
 
-    protected void addNotificationViews(Entry entry, Ranking ranking) {
+    protected void addNotificationViews(Entry entry, RankingMap ranking) {
         if (entry == null) {
             return;
         }
@@ -1206,7 +1245,7 @@
         updateNotifications();
     }
 
-    private void addNotificationViews(StatusBarNotification notification, Ranking ranking) {
+    private void addNotificationViews(StatusBarNotification notification, RankingMap ranking) {
         addNotificationViews(createNotificationViews(notification), ranking);
     }
 
@@ -1292,9 +1331,9 @@
     }
 
     public abstract void addNotificationInternal(StatusBarNotification notification,
-            Ranking ranking);
+            RankingMap ranking);
 
-    protected abstract void updateRankingInternal(Ranking ranking);
+    protected abstract void updateRankingInternal(RankingMap ranking);
 
     @Override
     public void removeNotification(String key) {
@@ -1303,7 +1342,7 @@
         }
     }
 
-    public abstract void removeNotificationInternal(String key, Ranking ranking);
+    public abstract void removeNotificationInternal(String key, RankingMap ranking);
 
     public void updateNotification(StatusBarNotification notification) {
         if (!USE_NOTIFICATION_LISTENER) {
@@ -1311,12 +1350,18 @@
         }
     }
 
-    public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
         if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
 
-        final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey());
+        final String key = notification.getKey();
+        boolean wasHeadsUp = isHeadsUp(key);
+        NotificationData.Entry oldEntry;
+        if (wasHeadsUp) {
+            oldEntry = mHeadsUpNotificationView.getEntry();
+        } else {
+            oldEntry = mNotificationData.findByKey(key);
+        }
         if (oldEntry == null) {
-            Log.w(TAG, "updateNotification for unknown key: " + notification.getKey());
             return;
         }
 
@@ -1382,61 +1427,99 @@
                         && oldPublicContentView.getPackage() != null
                         && oldPublicContentView.getPackage().equals(publicContentView.getPackage())
                         && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
-
-
         boolean updateTicker = notification.getNotification().tickerText != null
                 && !TextUtils.equals(notification.getNotification().tickerText,
                 oldEntry.notification.getNotification().tickerText);
+
+        final boolean shouldInterrupt = shouldInterrupt(notification);
+        final boolean alertAgain = alertAgain(oldEntry);
+        boolean updateSuccessful = false;
         if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged
                 && publicUnchanged) {
-            if (DEBUG) Log.d(TAG, "reusing notification for key: " + notification.getKey());
+            if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
             oldEntry.notification = notification;
             try {
-                updateNotificationViews(oldEntry, notification);
-
-                if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
-                        && oldNotification == mInterruptingNotificationEntry.notification) {
-                    if (!shouldInterrupt(notification)) {
-                        if (DEBUG) Log.d(TAG, "no longer interrupts!");
-                        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
-                    } else {
-                        if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
-                        mInterruptingNotificationEntry.notification = notification;
-                        updateHeadsUpViews(mInterruptingNotificationEntry, notification);
+                if (oldEntry.icon != null) {
+                    // Update the icon
+                    final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+                            notification.getUser(),
+                            notification.getNotification().icon,
+                            notification.getNotification().iconLevel,
+                            notification.getNotification().number,
+                            notification.getNotification().tickerText);
+                    if (!oldEntry.icon.set(ic)) {
+                        handleNotificationError(notification, "Couldn't update icon: " + ic);
+                        return;
                     }
                 }
 
-                // Update the icon.
-                final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
-                        notification.getUser(),
-                        notification.getNotification().icon, notification.getNotification().iconLevel,
-                        notification.getNotification().number,
-                        notification.getNotification().tickerText);
-                if (!oldEntry.icon.set(ic)) {
-                    handleNotificationError(notification, "Couldn't update icon: " + ic);
-                    return;
+                if (wasHeadsUp) {
+                    if (shouldInterrupt) {
+                        updateHeadsUpViews(oldEntry, notification);
+                        if (alertAgain) {
+                            resetHeadsUpDecayTimer();
+                        }
+                    } else {
+                        // we updated the notification above, so release to build a new shade entry
+                        mHeadsUpNotificationView.releaseAndClose();
+                        return;
+                    }
+                } else {
+                    if (shouldInterrupt && alertAgain) {
+                        removeNotificationViews(key, ranking);
+                        addNotificationInternal(notification, ranking);  //this will pop the headsup
+                    } else {
+                        updateNotificationViews(oldEntry, notification);
+                    }
                 }
                 mNotificationData.updateRanking(ranking);
                 updateNotifications();
+                updateSuccessful = true;
             }
             catch (RuntimeException e) {
                 // It failed to add cleanly.  Log, and remove the view from the panel.
                 Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
-                removeNotificationViews(notification.getKey(), ranking);
-                addNotificationViews(notification, ranking);
             }
-        } else {
-            if (DEBUG) Log.d(TAG, "not reusing notification for key: " + notification.getKey());
-            if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
-            removeNotificationViews(notification.getKey(), ranking);
-            addNotificationViews(notification, ranking);  // will also replace the heads up
-            final NotificationData.Entry newEntry = mNotificationData.findByKey(
-                    notification.getKey());
-            final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
-            if (userChangedExpansion) {
-                boolean userExpanded = oldEntry.row.isUserExpanded();
-                newEntry.row.setUserExpanded(userExpanded);
-                newEntry.row.notifyHeightChanged();
+        }
+        if (!updateSuccessful) {
+            if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
+            if (wasHeadsUp) {
+                if (shouldInterrupt) {
+                    if (DEBUG) Log.d(TAG, "rebuilding heads up for key: " + key);
+                    Entry newEntry = new Entry(notification, null);
+                    ViewGroup holder = mHeadsUpNotificationView.getHolder();
+                    if (inflateViewsForHeadsUp(newEntry, holder)) {
+                        mHeadsUpNotificationView.showNotification(newEntry);
+                        if (alertAgain) {
+                            resetHeadsUpDecayTimer();
+                        }
+                    } else {
+                        Log.w(TAG, "Couldn't create new updated headsup for package "
+                                + contentView.getPackage());
+                    }
+                } else {
+                    if (DEBUG) Log.d(TAG, "releasing heads up for key: " + key);
+                    oldEntry.notification = notification;
+                    mHeadsUpNotificationView.releaseAndClose();
+                    return;
+                }
+            } else {
+                if (shouldInterrupt && alertAgain) {
+                    if (DEBUG) Log.d(TAG, "reposting to invoke heads up for key: " + key);
+                    removeNotificationViews(key, ranking);
+                    addNotificationInternal(notification, ranking);  //this will pop the headsup
+                } else {
+                    if (DEBUG) Log.d(TAG, "rebuilding update in place for key: " + key);
+                    removeNotificationViews(key, ranking);
+                    addNotificationViews(notification, ranking);
+                    final NotificationData.Entry newEntry = mNotificationData.findByKey(key);
+                    final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
+                    if (userChangedExpansion) {
+                        boolean userExpanded = oldEntry.row.isUserExpanded();
+                        newEntry.row.setUserExpanded(userExpanded);
+                        newEntry.row.notifyHeightChanged();
+                    }
+                }
             }
         }
 
@@ -1511,11 +1594,17 @@
     }
 
     protected void notifyHeadsUpScreenOn(boolean screenOn) {
-        if (!screenOn && mInterruptingNotificationEntry != null) {
-            mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
+        if (!screenOn) {
+            scheduleHeadsUpEscalation();
         }
     }
 
+    private boolean alertAgain(Entry entry) {
+        final StatusBarNotification sbn = entry.notification;
+        return entry == null || !entry.hasInterrupted()
+                || (sbn.getNotification().flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
+    }
+
     protected boolean shouldInterrupt(StatusBarNotification sbn) {
         Notification notification = sbn.getNotification();
         // some predicates to make the boolean logic legible
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index 4233ab8..bfa74fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -21,6 +21,7 @@
 import android.os.Process;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -58,17 +59,18 @@
         updateSyntheticNotification();
     }
 
-    public boolean tryIntercept(StatusBarNotification notification, Ranking ranking) {
-        if (ranking == null) return false;
+    public boolean tryIntercept(StatusBarNotification notification, RankingMap rankingMap) {
+        if (rankingMap == null) return false;
         if (shouldDisplayIntercepted()) return false;
         if (mReleased.contains(notification.getKey())) return false;
-        if (!ranking.isInterceptedByDoNotDisturb(notification.getKey())) return false;
+        Ranking ranking = rankingMap.getRanking(notification.getKey());
+        if (!ranking.isInterceptedByDoNotDisturb()) return false;
         mIntercepted.put(notification.getKey(), notification);
         updateSyntheticNotification();
         return true;
     }
 
-    public void retryIntercepts(Ranking ranking) {
+    public void retryIntercepts(RankingMap ranking) {
         if (ranking == null) return;
 
         final int N = mIntercepted.size();
@@ -111,7 +113,7 @@
             return;
         }
         final Notification n = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_qs_zen_on)
+                .setSmallIcon(R.drawable.ic_notify_zen)
                 .setContentTitle(mContext.getResources().getQuantityString(
                         R.plurals.zen_mode_notification_title,
                         mIntercepted.size(), mIntercepted.size()))
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 631e19c..9921c55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -18,6 +18,7 @@
 
 import android.app.Notification;
 import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 
@@ -67,15 +68,23 @@
         public void setInterruption() {
             interruption = true;
         }
+
+        public boolean hasInterrupted() {
+            return interruption;
+        }
     }
 
     private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
-    private Ranking mRanking;
+    private RankingMap mRanking;
     private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() {
         @Override
         public int compare(Entry a, Entry b) {
             if (mRanking != null) {
-                return mRanking.getRank(a.key) - mRanking.getRank(b.key);
+                Ranking aRanking = mRanking.getRanking(a.key);
+                Ranking bRanking = mRanking.getRanking(b.key);
+                int aRank = aRanking != null ? aRanking.getRank() : -1;
+                int bRank = bRanking != null ? bRanking.getRank() : -1;
+                return aRank - bRank;
             }
 
             final StatusBarNotification na = a.notification;
@@ -108,12 +117,12 @@
         return null;
     }
 
-    public void add(Entry entry, Ranking ranking) {
+    public void add(Entry entry, RankingMap ranking) {
         mEntries.add(entry);
         updateRankingAndSort(ranking);
     }
 
-    public Entry remove(String key, Ranking ranking) {
+    public Entry remove(String key, RankingMap ranking) {
         Entry e = findByKey(key);
         if (e == null) {
             return null;
@@ -123,7 +132,7 @@
         return e;
     }
 
-    public void updateRanking(Ranking ranking) {
+    public void updateRanking(RankingMap ranking) {
         updateRankingAndSort(ranking);
     }
 
@@ -137,12 +146,13 @@
                 }
             }
         } else {
-            return mRanking.isAmbient(key);
+            Ranking ranking = mRanking.getRanking(key);
+            return ranking != null && ranking.isAmbient();
         }
         return false;
     }
 
-    private void updateRankingAndSort(Ranking ranking) {
+    private void updateRankingAndSort(RankingMap ranking) {
         if (ranking != null) {
             mRanking = ranking;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java
index 6819d9b..ce5ab5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowIconsView.java
@@ -65,7 +65,7 @@
     }
 
     private void applyColor(Notification notification, StatusBarIconView view) {
-        if (notification.color != Notification.COLOR_DEFAULT) {
+        if (notification.color == Notification.COLOR_DEFAULT) {
             if (mNotificationColorUtil.isGrayscale(view.getDrawable())) {
                 view.setColorFilter(mTintColor, PorterDuff.Mode.MULTIPLY);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
deleted file mode 100644
index 1503072..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * An single dot of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
- */
-public class SpeedBumpDotView extends View {
-
-    private final Paint mPaint = new Paint();
-
-    public SpeedBumpDotView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mPaint.setAntiAlias(true);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        float radius = getWidth() / 2.0f;
-        canvas.drawCircle(radius, radius, radius, mPaint);
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-
-    public void setColor(int color) {
-        mPaint.setColor(color);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java
deleted file mode 100644
index cac6327..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.view.View;
-import com.android.systemui.R;
-
-/**
- * The Algorithm of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout} which can be
- * queried for {@link * com.android.systemui.statusbar.SpeedBumpDotsState}
- */
-public class SpeedBumpDotsAlgorithm {
-
-    private final float mDotRadius;
-
-    public SpeedBumpDotsAlgorithm(Context context) {
-        mDotRadius = context.getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height)
-                / 2.0f;
-    }
-
-    public void getState(SpeedBumpDotsState resultState) {
-
-        // First reset the current state and ensure that every View has a ViewState
-        resultState.resetViewStates();
-
-        SpeedBumpDotsLayout hostView = resultState.getHostView();
-        boolean currentlyVisible = hostView.isCurrentlyVisible();
-        resultState.setActiveState(currentlyVisible
-                ? SpeedBumpDotsState.SHOWN
-                : SpeedBumpDotsState.HIDDEN);
-        int hostWidth = hostView.getWidth();
-        float layoutWidth = hostWidth - 2 * mDotRadius;
-        int childCount = hostView.getChildCount();
-        float paddingBetween = layoutWidth / (childCount - 1);
-        float centerY = hostView.getHeight() / 2.0f;
-        for (int i = 0; i < childCount; i++) {
-            View child = hostView.getChildAt(i);
-            SpeedBumpDotsState.ViewState viewState = resultState.getViewStateForView(child);
-            if (currentlyVisible) {
-                float xTranslation = i * paddingBetween;
-                viewState.xTranslation = xTranslation;
-                viewState.yTranslation = calculateYTranslation(hostView, centerY, xTranslation,
-                        layoutWidth);
-            } else {
-                viewState.xTranslation = layoutWidth / 2;
-                viewState.yTranslation = centerY - mDotRadius;
-            }
-            viewState.alpha = currentlyVisible ? 1.0f : 0.0f;
-            viewState.scale = currentlyVisible ? 1.0f : 0.5f;
-        }
-    }
-
-    private float calculateYTranslation(SpeedBumpDotsLayout hostView, float centerY,
-            float xTranslation, float layoutWidth) {
-        float t = hostView.getAnimationProgress();
-        if (t == 0.0f || t == 1.0f) {
-            return centerY - mDotRadius;
-        }
-        float damping = (0.5f -Math.abs(0.5f - t)) * 1.3f;
-        float partialOffset = xTranslation / layoutWidth;
-        float indentFactor = (float) (Math.sin((t + partialOffset * 1.5f) * - Math.PI) * damping);
-        return (1.0f - indentFactor) * centerY - mDotRadius;
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java
deleted file mode 100644
index ddf5215..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.animation.TimeAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import com.android.systemui.R;
-
-/**
- * A layout with a certain number of dots which are integrated in the
- * {@link com.android.systemui.statusbar.SpeedBumpView}
- */
-public class SpeedBumpDotsLayout extends ViewGroup {
-
-    private static final float DOT_CLICK_ANIMATION_LENGTH = 300;
-    private final int mDotSize;
-    private final SpeedBumpDotsAlgorithm mAlgorithm = new SpeedBumpDotsAlgorithm(getContext());
-    private final SpeedBumpDotsState mCurrentState = new SpeedBumpDotsState(this);
-    private boolean mIsCurrentlyVisible = true;
-    private final ValueAnimator mClickAnimator;
-    private float mAnimationProgress;
-    private ValueAnimator.AnimatorUpdateListener mClickUpdateListener
-            = new ValueAnimator.AnimatorUpdateListener() {
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            mAnimationProgress = animation.getAnimatedFraction();
-            updateChildren();
-        }
-    };
-
-    public SpeedBumpDotsLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mDotSize = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
-        createDots(context, attrs);
-        mClickAnimator = TimeAnimator.ofFloat(0, DOT_CLICK_ANIMATION_LENGTH);
-        mClickAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
-        mClickAnimator.addUpdateListener(mClickUpdateListener);
-    }
-
-    private void createDots(Context context, AttributeSet attrs) {
-        SpeedBumpDotView blueDot = new SpeedBumpDotView(context, attrs);
-        blueDot.setColor(getResources().getColor(R.color.speed_bump_dot_blue));
-        addView(blueDot);
-
-        SpeedBumpDotView redDot = new SpeedBumpDotView(context, attrs);
-        redDot.setColor(getResources().getColor(R.color.speed_bump_dot_red));
-        addView(redDot);
-
-        SpeedBumpDotView yellowDot = new SpeedBumpDotView(context, attrs);
-        yellowDot.setColor(getResources().getColor(R.color.speed_bump_dot_yellow));
-        addView(yellowDot);
-
-        SpeedBumpDotView greenDot = new SpeedBumpDotView(context, attrs);
-        greenDot.setColor(getResources().getColor(R.color.speed_bump_dot_green));
-        addView(greenDot);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int childWidthSpec = MeasureSpec.makeMeasureSpec(mDotSize,
-                MeasureSpec.getMode(widthMeasureSpec));
-        int childHeightSpec = MeasureSpec.makeMeasureSpec(mDotSize,
-                MeasureSpec.getMode(heightMeasureSpec));
-        measureChildren(childWidthSpec, childHeightSpec);
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = getChildAt(i);
-            child.layout(0, 0, mDotSize, mDotSize);
-        }
-        if (changed) {
-            updateChildren();
-        }
-    }
-
-    private void updateChildren() {
-        mAlgorithm.getState(mCurrentState);
-        mCurrentState.apply();
-    }
-
-    public void performVisibilityAnimation(boolean visible) {
-        if (mClickAnimator.isRunning()) {
-            mClickAnimator.cancel();
-        }
-        mIsCurrentlyVisible = visible;
-        mAlgorithm.getState(mCurrentState);
-        mCurrentState.animateToState();
-    }
-
-    public void setInvisible() {
-        mIsCurrentlyVisible = false;
-        mAlgorithm.getState(mCurrentState);
-        mCurrentState.apply();
-    }
-
-    public boolean isCurrentlyVisible() {
-        return mIsCurrentlyVisible;
-    }
-
-    public void performDotClickAnimation() {
-        if (mClickAnimator.isRunning()) {
-            // don't perform an animation if it's running already
-            return;
-        }
-        mClickAnimator.start();
-    }
-
-
-    public float getAnimationProgress() {
-        return mAnimationProgress;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
deleted file mode 100644
index 4febab1..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A state of a {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
- */
-public class SpeedBumpDotsState {
-
-    public static final int HIDDEN = 1;
-    public static final int SHOWN = 2;
-    private static final int VISIBILITY_ANIMATION_DELAY_PER_ELEMENT = 80;
-
-    private final SpeedBumpDotsLayout mHostView;
-    private final HashMap<View, ViewState> mStateMap = new HashMap<View, ViewState>();
-    private final Interpolator mFastOutSlowInInterpolator;
-    private int mActiveState = 0;
-
-    public SpeedBumpDotsState(SpeedBumpDotsLayout hostLayout) {
-        mHostView = hostLayout;
-        mFastOutSlowInInterpolator = AnimationUtils
-                .loadInterpolator(hostLayout.getContext(),
-                        android.R.interpolator.fast_out_slow_in);
-    }
-
-    public SpeedBumpDotsLayout getHostView() {
-        return mHostView;
-    }
-
-    public void resetViewStates() {
-        int numChildren = mHostView.getChildCount();
-        for (int i = 0; i < numChildren; i++) {
-            View child = mHostView.getChildAt(i);
-            ViewState viewState = mStateMap.get(child);
-            if (viewState == null) {
-                viewState = new ViewState();
-                mStateMap.put(child, viewState);
-            }
-        }
-    }
-
-    public ViewState getViewStateForView(View requestedView) {
-        return mStateMap.get(requestedView);
-    }
-
-    public void apply() {
-        int childCount = mHostView.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = mHostView.getChildAt(i);
-            ViewState viewState = mStateMap.get(child);
-
-            child.setTranslationX(viewState.xTranslation);
-            child.setTranslationY(viewState.yTranslation);
-            child.setScaleX(viewState.scale);
-            child.setScaleY(viewState.scale);
-            child.setAlpha(viewState.alpha);
-        }
-    }
-
-    public void animateToState() {
-        int childCount = mHostView.getChildCount();
-        int middleIndex = (childCount - 1) / 2;
-        long delayPerElement = VISIBILITY_ANIMATION_DELAY_PER_ELEMENT;
-        boolean isAppearing = getActiveState() == SHOWN;
-        boolean isDisappearing = getActiveState() == HIDDEN;
-        for (int i = 0; i < childCount; i++) {
-            int delayIndex;
-            if (i <= middleIndex) {
-                delayIndex = i * 2;
-            } else {
-                int distToMiddle = i - middleIndex;
-                delayIndex = (childCount - 1) - (distToMiddle - 1) * 2;
-            }
-            long startDelay = 0;
-            if (isAppearing || isDisappearing) {
-                if (isDisappearing) {
-                    delayIndex = childCount - 1 - delayIndex;
-                }
-                startDelay = delayIndex * delayPerElement;
-            }
-            View child = mHostView.getChildAt(i);
-            ViewState viewState = mStateMap.get(child);
-            child.animate().setInterpolator(mFastOutSlowInInterpolator)
-                    .setStartDelay(startDelay)
-                    .alpha(viewState.alpha)
-                    .translationX(viewState.xTranslation)
-                    .translationY(viewState.yTranslation)
-                    .scaleX(viewState.scale).scaleY(viewState.scale);
-        }
-    }
-
-    public int getActiveState() {
-        return mActiveState;
-    }
-
-    public void setActiveState(int mActiveState) {
-        this.mActiveState = mActiveState;
-    }
-
-    public static class ViewState {
-        float xTranslation;
-        float yTranslation;
-        float alpha;
-        float scale;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
index 689d0e9..f80f0fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
@@ -16,71 +16,26 @@
 
 package com.android.systemui.statusbar;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.content.Context;
-import android.graphics.Outline;
 import android.util.AttributeSet;
-import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
-import android.widget.TextView;
 import com.android.systemui.R;
 
 /**
  * The view representing the separation between important and less important notifications
  */
-public class SpeedBumpView extends ExpandableView implements View.OnClickListener {
+public class SpeedBumpView extends ExpandableView {
 
-    private final int mCollapsedHeight;
-    private final int mDotsHeight;
-    private final int mTextPaddingInset;
-    private SpeedBumpDotsLayout mDots;
-    private AlphaOptimizedView mLineLeft;
-    private AlphaOptimizedView mLineRight;
-    private boolean mIsExpanded;
-    private boolean mDividerVisible = true;
-    private ValueAnimator mCurrentAnimator;
+    private final int mSpeedBumpHeight;
+    private AlphaOptimizedView mLine;
+    private boolean mIsVisible = true;
     private final Interpolator mFastOutSlowInInterpolator;
-    private float mCenterX;
-    private TextView mExplanationText;
-    private boolean mExplanationTextVisible = false;
-    private AnimatorListenerAdapter mHideExplanationListener = new AnimatorListenerAdapter() {
-        private boolean mCancelled;
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (!mCancelled) {
-                mExplanationText.setVisibility(View.INVISIBLE);
-            }
-        }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-            mCancelled = true;
-        }
-
-        @Override
-        public void onAnimationStart(Animator animation) {
-            mCancelled = false;
-        }
-    };
-    private Animator.AnimatorListener mAnimationFinishedListener = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mCurrentAnimator = null;
-        }
-    };
 
     public SpeedBumpView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mCollapsedHeight = getResources()
-                .getDimensionPixelSize(R.dimen.speed_bump_height_collapsed);
-        mTextPaddingInset = getResources().getDimensionPixelSize(
-                R.dimen.speed_bump_text_padding_inset);
-        mDotsHeight = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
-        setOnClickListener(this);
+        mSpeedBumpHeight = getResources()
+                .getDimensionPixelSize(R.dimen.speed_bump_height);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
                 android.R.interpolator.fast_out_slow_in);
     }
@@ -88,111 +43,41 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mDots = (SpeedBumpDotsLayout) findViewById(R.id.speed_bump_dots_layout);
-        mLineLeft = (AlphaOptimizedView) findViewById(R.id.speedbump_line_left);
-        mLineRight = (AlphaOptimizedView) findViewById(R.id.speedbump_line_right);
-        mExplanationText = (TextView) findViewById(R.id.speed_bump_text);
-        resetExplanationText();
-
+        mLine = (AlphaOptimizedView) findViewById(R.id.speedbump_line);
     }
 
     @Override
     protected int getInitialHeight() {
-        return mCollapsedHeight;
+        return mSpeedBumpHeight;
     }
 
     @Override
     public int getIntrinsicHeight() {
-        if (mCurrentAnimator != null) {
-            // expand animation is running
-            return getActualHeight();
-        }
-        return mIsExpanded ? getHeight() : mCollapsedHeight;
+        return mSpeedBumpHeight;
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-        Outline outline = new Outline();
-        mCenterX = getWidth() / 2;
-        float centerY = getHeight() / 2;
-        // TODO: hide outline better
-        // Temporary workaround to hide outline on a transparent view
-        int outlineLeft = (int) (mCenterX - getResources().getDisplayMetrics().densityDpi * 8);
-        int outlineTop = (int) (centerY - mDotsHeight / 2);
-        outline.setOval(outlineLeft, outlineTop, outlineLeft + mDotsHeight,
-                outlineTop + mDotsHeight);
-        setOutline(outline);
-        mLineLeft.setPivotX(mLineLeft.getWidth());
-        mLineLeft.setPivotY(mLineLeft.getHeight() / 2);
-        mLineRight.setPivotX(0);
-        mLineRight.setPivotY(mLineRight.getHeight() / 2);
+        mLine.setPivotX(mLine.getWidth() / 2);
+        mLine.setPivotY(mLine.getHeight() / 2);
+        setOutline(null);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         measureChildren(widthMeasureSpec, heightMeasureSpec);
-        int height = mCollapsedHeight + mExplanationText.getMeasuredHeight() - mTextPaddingInset;
+        int height = mSpeedBumpHeight;
         setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
     }
 
     @Override
-    public void onClick(View v) {
-        if (mCurrentAnimator != null) {
-            return;
-        }
-        int startValue = mIsExpanded ? getMaxHeight() : mCollapsedHeight;
-        int endValue = mIsExpanded ? mCollapsedHeight : getMaxHeight();
-        mCurrentAnimator = ValueAnimator.ofInt(startValue, endValue);
-        mCurrentAnimator.setInterpolator(mFastOutSlowInInterpolator);
-        mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                setActualHeight((int) animation.getAnimatedValue());
-            }
-        });
-        mCurrentAnimator.addListener(mAnimationFinishedListener);
-        mCurrentAnimator.start();
-        mIsExpanded = !mIsExpanded;
-        mDots.performDotClickAnimation();
-        animateExplanationTextInternal(mIsExpanded);
-    }
-
-    private void animateExplanationTextInternal(boolean visible) {
-        if (mExplanationTextVisible != visible) {
-            float translationY = 0.0f;
-            float scale = 0.5f;
-            float alpha = 0.0f;
-            boolean needsHideListener = true;
-            if (visible) {
-                mExplanationText.setVisibility(VISIBLE);
-                translationY = mDots.getBottom() - mTextPaddingInset;
-                scale = 1.0f;
-                alpha = 1.0f;
-                needsHideListener = false;
-            }
-            mExplanationText.animate().setInterpolator(mFastOutSlowInInterpolator)
-                    .alpha(alpha)
-                    .scaleX(scale)
-                    .scaleY(scale)
-                    .translationY(translationY)
-                    .setListener(needsHideListener ? mHideExplanationListener : null);
-            mExplanationTextVisible = visible;
-        }
-    }
-
-    @Override
     public boolean isTransparent() {
         return true;
     }
 
     public void performVisibilityAnimation(boolean nowVisible) {
         animateDivider(nowVisible, null /* onFinishedRunnable */);
-
-        // Animate explanation Text
-        if (mIsExpanded) {
-            animateExplanationTextInternal(nowVisible);
-        }
     }
 
     /**
@@ -203,28 +88,16 @@
      *        finished.
      */
     public void animateDivider(boolean nowVisible, Runnable onFinishedRunnable) {
-        if (nowVisible != mDividerVisible) {
+        if (nowVisible != mIsVisible) {
             // Animate dividers
             float endValue = nowVisible ? 1.0f : 0.0f;
-            float endTranslationXLeft = nowVisible ? 0.0f : mCenterX - mLineLeft.getRight();
-            float endTranslationXRight = nowVisible ? 0.0f : mCenterX - mLineRight.getLeft();
-            mLineLeft.animate()
+            mLine.animate()
                     .alpha(endValue)
                     .scaleX(endValue)
                     .scaleY(endValue)
-                    .translationX(endTranslationXLeft)
                     .setInterpolator(mFastOutSlowInInterpolator)
                     .withEndAction(onFinishedRunnable);
-            mLineRight.animate()
-                    .alpha(endValue)
-                    .scaleX(endValue)
-                    .scaleY(endValue)
-                    .translationX(endTranslationXRight)
-                    .setInterpolator(mFastOutSlowInInterpolator);
-
-            // Animate dots
-            mDots.performVisibilityAnimation(nowVisible);
-            mDividerVisible = nowVisible;
+            mIsVisible = nowVisible;
         } else {
             if (onFinishedRunnable != null) {
                 onFinishedRunnable.run();
@@ -233,34 +106,10 @@
     }
 
     public void setInvisible() {
-        float endTranslationXLeft = mCenterX - mLineLeft.getRight();
-        float endTranslationXRight = mCenterX - mLineRight.getLeft();
-        mLineLeft.setAlpha(0.0f);
-        mLineLeft.setScaleX(0.0f);
-        mLineLeft.setScaleY(0.0f);
-        mLineLeft.setTranslationX(endTranslationXLeft);
-        mLineRight.setAlpha(0.0f);
-        mLineRight.setScaleX(0.0f);
-        mLineRight.setScaleY(0.0f);
-        mLineRight.setTranslationX(endTranslationXRight);
-        mDots.setInvisible();
-        resetExplanationText();
-
-        mDividerVisible = false;
-    }
-
-    public void collapse() {
-        if (mIsExpanded) {
-            setActualHeight(mCollapsedHeight);
-            mIsExpanded = false;
-        }
-        resetExplanationText();
-    }
-
-    public void animateExplanationText(boolean nowVisible) {
-        if (mIsExpanded) {
-            animateExplanationTextInternal(nowVisible);
-        }
+        mLine.setAlpha(0.0f);
+        mLine.setScaleX(0.0f);
+        mLine.setScaleY(0.0f);
+        mIsVisible = false;
     }
 
     @Override
@@ -272,17 +121,4 @@
     public void performAddAnimation(long delay) {
         performVisibilityAnimation(true);
     }
-
-    private void resetExplanationText() {
-        mExplanationText.setTranslationY(0);
-        mExplanationText.setVisibility(INVISIBLE);
-        mExplanationText.setAlpha(0.0f);
-        mExplanationText.setScaleX(0.5f);
-        mExplanationText.setScaleY(0.5f);
-        mExplanationTextVisible = false;
-    }
-
-    public boolean isExpanded() {
-        return mIsExpanded;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
index 086a266..e312d58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
@@ -423,6 +423,7 @@
             return;
         }
         if (!animate) {
+            view.animate().cancel();
             view.setAlpha(alpha);
             view.setScaleX(scale);
             view.setScaleY(scale);
@@ -465,6 +466,13 @@
     }
 
     public void reset() {
+        if (mSwipeAnimator != null) {
+            mSwipeAnimator.cancel();
+        }
+        ArrayList<View> targetViews = mCallback.getTranslationViews();
+        for (View view : targetViews) {
+            view.animate().cancel();
+        }
         setTranslation(0.0f, true);
         mSwipingInProgress = false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 34179cb..dde95bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -688,6 +688,9 @@
 
     @Override
     protected boolean isScrolledToBottom() {
+        if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
+            return true;
+        }
         if (!isInSettings()) {
             return mNotificationStackScroller.isScrolledToBottom();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 772d0e7..1f3098d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
+import android.view.ViewTreeObserver;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
@@ -67,6 +68,11 @@
     private VelocityTrackerInterface mVelocityTracker;
     private FlingAnimationUtils mFlingAnimationUtils;
 
+    /**
+     * Whether an instant expand request is currently pending and we are just waiting for layout.
+     */
+    private boolean mInstantExpanding;
+
     PanelBar mBar;
 
     protected int mMaxPanelHeight = -1;
@@ -128,6 +134,9 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
+        if (mInstantExpanding) {
+            return false;
+        }
 
         /*
          * We capture touch events here and update the expand height here in case according to
@@ -263,6 +272,9 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
+        if (mInstantExpanding) {
+            return false;
+        }
 
         /*
          * If the user drags anywhere inside the panel we intercept it if he moves his finger
@@ -556,6 +568,41 @@
         }
     }
 
+    public void instantExpand() {
+        mInstantExpanding = true;
+        abortAnimations();
+        if (mTracking) {
+            onTrackingStopped(true /* expands */); // The panel is expanded after this call.
+            onExpandingFinished();
+        }
+        setVisibility(VISIBLE);
+
+        // Wait for window manager to pickup the change, so we know the maximum height of the panel
+        // then.
+        getViewTreeObserver().addOnGlobalLayoutListener(
+                new ViewTreeObserver.OnGlobalLayoutListener() {
+                    @Override
+                    public void onGlobalLayout() {
+                        if (mStatusBar.getStatusBarWindow().getHeight()
+                                != mStatusBar.getStatusBarHeight()) {
+                            getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                            setExpandedFraction(1f);
+                            mInstantExpanding = false;
+                        }
+                    }
+                });
+
+        // Make sure a layout really happens.
+        requestLayout();
+    }
+
+    private void abortAnimations() {
+        cancelPeek();
+        if (mHeightAnimator != null) {
+            mHeightAnimator.cancel();
+        }
+    }
+
     protected void startUnlockHintAnimation() {
 
         // We don't need to hint the user if an animation is already running or the user is changing
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 5223217..c11a9ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -64,7 +64,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Global;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
@@ -103,6 +103,7 @@
 import com.android.systemui.qs.CircularClipper;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -278,10 +279,6 @@
     // the date view
     DateView mDateView;
 
-    // for heads up notifications
-    private HeadsUpNotificationView mHeadsUpNotificationView;
-    private int mHeadsUpNotificationDecay;
-
     // on-screen navigation buttons
     private NavigationBarView mNavigationBarView = null;
     private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
@@ -367,7 +364,7 @@
                 if (!mUseHeadsUp) {
                     Log.d(TAG, "dismissing any existing heads up notification on disable event");
                     setHeadsUpVisibility(false);
-                    mHeadsUpNotificationView.setNotification(null);
+                    mHeadsUpNotificationView.release();
                     removeHeadsUpView();
                 } else {
                     addHeadsUpView();
@@ -831,6 +828,10 @@
         return mStatusBarView;
     }
 
+    public StatusBarWindowView getStatusBarWindow() {
+        return mStatusBarWindow;
+    }
+
     @Override
     protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
         boolean opaque = false;
@@ -1063,7 +1064,7 @@
     }
 
     @Override
-    public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
         if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
         if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification, ranking)) {
             // Forward the ranking so we can sort the new notification.
@@ -1074,31 +1075,26 @@
         displayNotification(notification, ranking);
     }
 
-    public void displayNotification(StatusBarNotification notification,
-            Ranking ranking) {
-        Entry shadeEntry = createNotificationViews(notification);
-        if (shadeEntry == null) {
-            return;
-        }
+    public void displayNotification(StatusBarNotification notification, RankingMap ranking) {
         if (mUseHeadsUp && shouldInterrupt(notification)) {
             if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
             Entry interruptionCandidate = new Entry(notification, null);
             ViewGroup holder = mHeadsUpNotificationView.getHolder();
             if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
-                mInterruptingNotificationTime = System.currentTimeMillis();
-                mInterruptingNotificationEntry = interruptionCandidate;
-                shadeEntry.setInterruption();
-
                 // 1. Populate mHeadsUpNotificationView
-                mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
+                mHeadsUpNotificationView.showNotification(interruptionCandidate);
 
-                // 2. Animate mHeadsUpNotificationView in
-                mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
-
-                // 3. Set alarm to age the notification off
-                resetHeadsUpDecayTimer();
+                // do not show the notification in the shade, yet.
+                return;
             }
-        } else if (notification.getNotification().fullScreenIntent != null) {
+        }
+
+        Entry shadeEntry = createNotificationViews(notification);
+        if (shadeEntry == null) {
+            return;
+        }
+
+        if (notification.getNotification().fullScreenIntent != null) {
             // Stop screensaver if the notification has a full-screen intent.
             // (like an incoming phone call)
             awakenDreams();
@@ -1113,7 +1109,7 @@
             // usual case: status bar visible & not immersive
 
             // show the ticker if there isn't already a heads up
-            if (mInterruptingNotificationEntry == null) {
+            if (mHeadsUpNotificationView.getEntry() == null) {
                 tick(notification, true);
             }
         }
@@ -1123,31 +1119,64 @@
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
     }
 
+    public void displayNotificationFromHeadsUp(StatusBarNotification notification) {
+        NotificationData.Entry shadeEntry = createNotificationViews(notification);
+        if (shadeEntry == null) {
+            return;
+        }
+        shadeEntry.setInterruption();
+
+        addNotificationViews(shadeEntry, null);
+        // Recalculate the position of the sliding windows and the titles.
+        setAreThereNotifications();
+        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+    }
+
     @Override
     public void resetHeadsUpDecayTimer() {
-        mHandler.removeMessages(MSG_HIDE_HEADS_UP);
+        mHandler.removeMessages(MSG_DECAY_HEADS_UP);
         if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
                 && mHeadsUpNotificationView.isClearable()) {
-            mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
+            mHandler.sendEmptyMessageDelayed(MSG_DECAY_HEADS_UP, mHeadsUpNotificationDecay);
         }
     }
 
     @Override
-    public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void scheduleHeadsUpOpen() {
+        mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
+    }
+
+    @Override
+    public void scheduleHeadsUpClose() {
+        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+    }
+
+    @Override
+    public void scheduleHeadsUpEscalation() {
+        mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
+    }
+
+    @Override
+    public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
         super.updateNotificationInternal(notification, ranking);
         // if we're here, then the notification is already in the shade
         mIntercepted.remove(notification.getKey());
     }
 
     @Override
-    protected void updateRankingInternal(Ranking ranking) {
+    protected void updateRankingInternal(RankingMap ranking) {
         mNotificationData.updateRanking(ranking);
         mIntercepted.retryIntercepts(ranking);
         updateNotifications();
     }
 
     @Override
-    public void removeNotificationInternal(String key, Ranking ranking) {
+    public void removeNotificationInternal(String key, RankingMap ranking) {
+        if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null
+                && key.equals(mHeadsUpNotificationView.getEntry().notification.getKey())) {
+            mHeadsUpNotificationView.clear();
+        }
+
         StatusBarNotification old = removeNotificationViews(key, ranking);
         if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
 
@@ -1160,11 +1189,6 @@
             // Recalculate the position of the sliding windows and the titles.
             updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
 
-            if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
-                    && old == mInterruptingNotificationEntry.notification) {
-                mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
-            }
-
             if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
                     && !mNotificationPanel.isTracking() && mState != StatusBarState.KEYGUARD) {
                 animateCollapsePanels();
@@ -1586,7 +1610,12 @@
                 case MSG_SHOW_HEADS_UP:
                     setHeadsUpVisibility(true);
                     break;
+                case MSG_DECAY_HEADS_UP:
+                    mHeadsUpNotificationView.release();
+                    setHeadsUpVisibility(false);
+                    break;
                 case MSG_HIDE_HEADS_UP:
+                    mHeadsUpNotificationView.release();
                     setHeadsUpVisibility(false);
                     break;
                 case MSG_ESCALATE_HEADS_UP:
@@ -1599,8 +1628,9 @@
 
     /**  if the interrupting notification had a fullscreen intent, fire it now.  */
     private void escalateHeadsUp() {
-        if (mInterruptingNotificationEntry != null) {
-            final StatusBarNotification sbn = mInterruptingNotificationEntry.notification;
+        if (mHeadsUpNotificationView.getEntry() != null) {
+            final StatusBarNotification sbn = mHeadsUpNotificationView.getEntry().notification;
+            mHeadsUpNotificationView.release();
             final Notification notification = sbn.getNotification();
             if (notification.fullScreenIntent != null) {
                 if (DEBUG)
@@ -2255,7 +2285,7 @@
         pw.print("  mUseHeadsUp=");
         pw.println(mUseHeadsUp);
         pw.print("  interrupting package: ");
-        pw.println(hunStateToString(mInterruptingNotificationEntry));
+        pw.println(hunStateToString(mHeadsUpNotificationView.getEntry()));
         dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
         if (mNavigationBarView != null) {
             pw.print("  mNavigationBarWindowState=");
@@ -2506,6 +2536,7 @@
         repositionNavigationBar();
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
         updateShowSearchHoldoff();
+        updateRowStates();
     }
 
     @Override
@@ -2529,26 +2560,10 @@
         if (!ENABLE_HEADS_UP) return;
         if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
         mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
-        if (!vis) {
-            if (DEBUG) Log.d(TAG, "setting heads up entry to null");
-            mInterruptingNotificationEntry = null;
-        }
     }
 
     public void onHeadsUpDismissed() {
-        if (mInterruptingNotificationEntry == null) return;
-        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
-        if (mHeadsUpNotificationView.isClearable()) {
-            try {
-                mBarService.onNotificationClear(
-                        mInterruptingNotificationEntry.notification.getPackageName(),
-                        mInterruptingNotificationEntry.notification.getTag(),
-                        mInterruptingNotificationEntry.notification.getId(),
-                        mInterruptingNotificationEntry.notification.getUserId());
-            } catch (android.os.RemoteException ex) {
-                // oh well
-            }
-        }
+        mHeadsUpNotificationView.dismiss();
     }
 
     /**
@@ -2917,7 +2932,6 @@
             mNotificationPanel.setKeyguardShowing(false);
             mScrimController.setKeyguardShowing(false);
         }
-
         updateStackScrollerState();
         updatePublicMode();
         updateNotifications();
@@ -2933,6 +2947,11 @@
                 ? View.INVISIBLE : View.VISIBLE);
         mStackScroller.setScrollingEnabled(!onKeyguard);
         mStackScroller.setExpandingEnabled(!onKeyguard);
+        ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
+        mStackScroller.setActivatedChild(null);
+        if (activatedChild != null) {
+            activatedChild.makeInactive(false /* animate */);
+        }
     }
 
     public void userActivity() {
@@ -2966,22 +2985,9 @@
 
     private void instantExpandNotificationsPanel() {
 
-        // Make our window larger and the panel visible.
+        // Make our window larger and the panel expanded.
         makeExpandedVisible(true);
-        mNotificationPanel.setVisibility(View.VISIBLE);
-
-        // Wait for window manager to pickup the change, so we know the maximum height of the panel
-        // then.
-        mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-            @Override
-            public void onGlobalLayout() {
-                if (mStatusBarWindow.getHeight() != getStatusBarHeight()) {
-                    mNotificationPanel.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                    mNotificationPanel.setExpandedFraction(1);
-                }
-            }
-        });
+        mNotificationPanel.instantExpand();
     }
 
     private void instantCollapseNotificationPanel() {
@@ -2989,9 +2995,13 @@
     }
 
     @Override
-    public void onActivated(View view) {
+    public void onActivated(ActivatableNotificationView view) {
         userActivity();
         mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
+        ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
+        if (previousView != null) {
+            previousView.makeInactive(true /* animate */);
+        }
         mStackScroller.setActivatedChild(view);
     }
 
@@ -3004,7 +3014,7 @@
     }
 
     @Override
-    public void onActivationReset(View view) {
+    public void onActivationReset(ActivatableNotificationView view) {
         if (view == mStackScroller.getActivatedChild()) {
             mKeyguardIndicationController.hideTransientIndication();
             mStackScroller.setActivatedChild(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 865aeff..7837769 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -64,6 +64,8 @@
 
     private int mKeyguardWidth = ViewGroup.LayoutParams.MATCH_PARENT;
     private int mNormalWidth;
+    private int mPadding;
+    private int mMultiUserExpandedMargin;
 
     private ActivityStarter mActivityStarter;
     private BrightnessController mBrightnessController;
@@ -112,6 +114,10 @@
         mKeyguardHeight = getResources().getDimensionPixelSize(
                 R.dimen.status_bar_header_height_keyguard);
         mNormalWidth = getLayoutParams().width;
+        mPadding = getResources().getDimensionPixelSize(R.dimen.notification_side_padding);
+        mMultiUserExpandedMargin =
+                getResources().getDimensionPixelSize(R.dimen.multi_user_switch_expanded_margin);
+
     }
 
     public void setActivityStarter(ActivityStarter activityStarter) {
@@ -139,6 +145,8 @@
             updateZTranslation();
             updateClickTargets();
             updateWidth();
+            updatePadding();
+            updateMultiUserSwitch();
             if (mQSPanel != null) {
                 mQSPanel.setExpanded(expanded && !overscrolled);
             }
@@ -229,6 +237,21 @@
         }
     }
 
+    private void updatePadding() {
+        boolean padded = !mKeyguardShowing || mExpanded;
+        int padding = padded ? mPadding : 0;
+        setPaddingRelative(padding, 0, padding, 0);
+    }
+
+    private void updateMultiUserSwitch() {
+        int marginEnd = !mKeyguardShowing || mExpanded ? mMultiUserExpandedMargin : 0;
+        MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams();
+        if (marginEnd != lp.getMarginEnd()) {
+            lp.setMarginEnd(marginEnd);
+            mMultiUserSwitch.setLayoutParams(lp);
+        }
+    }
+
     public void setExpansion(float height) {
         height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight;
         if (height < mCollapsedHeight) {
@@ -274,6 +297,8 @@
         updateWidth();
         updateVisibilities();
         updateZTranslation();
+        updatePadding();
+        updateMultiUserSwitch();
     }
 
     public void setUserInfoController(UserInfoController userInfoController) {
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 df01c12..0a48e34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -33,9 +33,9 @@
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
-import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback,
         ViewTreeObserver.OnComputeInternalInsetsListener {
@@ -51,7 +51,7 @@
     private SwipeHelper mSwipeHelper;
     private EdgeSwipeHelper mEdgeSwipeHelper;
 
-    private BaseStatusBar mBar;
+    private PhoneStatusBar mBar;
     private ExpandHelper mExpandHelper;
 
     private long mStartTouchTime;
@@ -69,7 +69,7 @@
         if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
     }
 
-    public void setBar(BaseStatusBar bar) {
+    public void setBar(PhoneStatusBar bar) {
         mBar = bar;
     }
 
@@ -77,7 +77,12 @@
         return mContentHolder;
     }
 
-    public boolean setNotification(NotificationData.Entry headsUp) {
+    public boolean showNotification(NotificationData.Entry headsUp) {
+        if (mHeadsUp != null && headsUp != null && !mHeadsUp.key.equals(headsUp.key)) {
+            // bump any previous heads up back to the shade
+            release();
+        }
+
         mHeadsUp = headsUp;
         if (mContentHolder != null) {
             mContentHolder.removeAllViews();
@@ -97,10 +102,57 @@
 
             mSwipeHelper.snapChild(mContentHolder, 1f);
             mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+
+            mHeadsUp.setInterruption();
+
+            // 2. Animate mHeadsUpNotificationView in
+            mBar.scheduleHeadsUpOpen();
+
+            // 3. Set alarm to age the notification off
+            mBar.resetHeadsUpDecayTimer();
         }
         return true;
     }
 
+    public boolean isShowing(String key) {
+        return mHeadsUp != null && mHeadsUp.key.equals(key);
+    }
+
+    /** Discard the Heads Up notification. */
+    public void clear() {
+        mHeadsUp = null;
+        mBar.scheduleHeadsUpClose();
+    }
+
+    /** Respond to dismissal of the Heads Up window. */
+    public void dismiss() {
+        if (mHeadsUp == null) return;
+        if (mHeadsUp.notification.isClearable()) {
+            mBar.onNotificationClear(mHeadsUp.notification);
+        } else {
+            release();
+        }
+        mHeadsUp = null;
+        mBar.scheduleHeadsUpClose();
+    }
+
+    /** Push any current Heads Up notification down into the shade. */
+    public void release() {
+        if (mHeadsUp != null) {
+            mBar.displayNotificationFromHeadsUp(mHeadsUp.notification);
+        }
+        mHeadsUp = null;
+    }
+
+    public void releaseAndClose() {
+        release();
+        mBar.scheduleHeadsUpClose();
+    }
+
+    public NotificationData.Entry getEntry() {
+        return mHeadsUp;
+    }
+
     public boolean isClearable() {
         return mHeadsUp == null || mHeadsUp.notification.isClearable();
     }
@@ -125,7 +177,7 @@
 
         if (mHeadsUp != null) {
             // whoops, we're on already!
-            setNotification(mHeadsUp);
+            showNotification(mHeadsUp);
         }
 
         getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -282,6 +334,10 @@
                 mTmpTwoArray[1] + mContentHolder.getHeight());
     }
 
+    public void escalate() {
+        mBar.scheduleHeadsUpEscalation();
+    }
+
     private class EdgeSwipeHelper implements Gefingerpoken {
         private static final boolean DEBUG_EDGE_SWIPE = false;
         private final float mTouchSlop;
@@ -335,4 +391,4 @@
             return mConsuming;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index dc8f315..1f68860 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -30,7 +30,7 @@
         void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description);
+                String dataTypeContentDescriptionId, String description, boolean noSim);
         void onAirplaneModeChanged(boolean enabled);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 56402a5..254a0e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -87,6 +87,7 @@
     int mQSDataTypeIconId;
     int mAirplaneIconId;
     boolean mDataActive;
+    boolean mNoSim;
     int mLastSignalLevel;
     boolean mShowPhoneRSSIForData = false;
     boolean mShowAtLeastThreeGees = false;
@@ -349,18 +350,18 @@
         if (isEmergencyOnly()) {
             cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
                     mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                    mContentDescriptionDataType, null);
+                    mContentDescriptionDataType, null, mNoSim);
         } else {
             if (mIsWimaxEnabled && mWimaxConnected) {
                 // Wimax is special
                 cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName);
+                        mContentDescriptionDataType, mNetworkName, mNoSim);
             } else {
                 // Normal mobile data
                 cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName);
+                        mContentDescriptionDataType, mNetworkName, mNoSim);
             }
         }
         cb.onAirplaneModeChanged(mAirplaneMode);
@@ -736,6 +737,7 @@
             // GSM case, we have to check also the sim state
             if (mSimState == IccCardConstants.State.READY ||
                     mSimState == IccCardConstants.State.UNKNOWN) {
+                mNoSim = false;
                 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
                     switch (mDataActivity) {
                         case TelephonyManager.DATA_ACTIVITY_IN:
@@ -758,6 +760,7 @@
                 }
             } else {
                 iconId = R.drawable.stat_sys_no_sim;
+                mNoSim = true;
                 visible = false; // no SIM? no data
             }
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index b21e12c..6d92b05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.stack;
 
 import android.view.View;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 
 import java.util.ArrayList;
 
@@ -27,7 +28,7 @@
     private ArrayList<View> mDraggedViews = new ArrayList<View>();
     private int mScrollY;
     private boolean mDimmed;
-    private View mActivatedChild;
+    private ActivatableNotificationView mActivatedChild;
     private float mOverScrollTopAmount;
     private float mOverScrollBottomAmount;
     private int mSpeedBumpIndex = -1;
@@ -64,7 +65,7 @@
      * In dimmed mode, a child can be activated, which happens on the first tap of the double-tap
      * interaction. This child is then scaled normally and its background is fully opaque.
      */
-    public void setActivatedChild(View activatedChild) {
+    public void setActivatedChild(ActivatableNotificationView activatedChild) {
         mActivatedChild = activatedChild;
     }
 
@@ -72,7 +73,7 @@
         return mDimmed;
     }
 
-    public View getActivatedChild() {
+    public ActivatableNotificationView getActivatedChild() {
         return mActivatedChild;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 5ace89f..4e1b686 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -33,6 +33,7 @@
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.SpeedBumpView;
@@ -240,11 +241,12 @@
         mBottomStackPeekSize = context.getResources()
                 .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
         mStackScrollAlgorithm = new StackScrollAlgorithm(context);
+        mStackScrollAlgorithm.setDimmed(mAmbientState.isDimmed());
         mPaddingBetweenElementsDimmed = context.getResources()
                 .getDimensionPixelSize(R.dimen.notification_padding_dimmed);
         mPaddingBetweenElementsNormal = context.getResources()
                 .getDimensionPixelSize(R.dimen.notification_padding);
-        updatePadding(false);
+        updatePadding(mAmbientState.isDimmed());
         int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
         int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
         mExpandHelper = new ExpandHelper(getContext(), this,
@@ -1722,7 +1724,6 @@
         mStackScrollAlgorithm.setIsExpanded(isExpanded);
         if (!isExpanded) {
             mOwnScrollY = 0;
-            mSpeedBumpView.collapse();
         }
     }
 
@@ -1760,7 +1761,7 @@
     /**
      * See {@link AmbientState#setActivatedChild}.
      */
-    public void setActivatedChild(View activatedChild) {
+    public void setActivatedChild(ActivatableNotificationView activatedChild) {
         mAmbientState.setActivatedChild(activatedChild);
         if (mAnimationsEnabled) {
             mActivateNeedsAnimation = true;
@@ -1769,7 +1770,7 @@
         requestChildrenUpdate();
     }
 
-    public View getActivatedChild() {
+    public ActivatableNotificationView getActivatedChild() {
         return mAmbientState.getActivatedChild();
     }
 
@@ -1791,7 +1792,6 @@
             int newVisibility = visible ? VISIBLE : GONE;
             mSpeedBumpView.setVisibility(newVisibility);
             if (visible) {
-                mSpeedBumpView.collapse();
                 // Make invisible to ensure that the appear animation is played.
                 mSpeedBumpView.setInvisible();
                 if (!mIsExpansionChanging) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index d6ff4fc..cbad9dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -186,7 +186,7 @@
             if (!child.isTransparent()) {
                 // Only update the previous values if we are not transparent,
                 // otherwise we would clip to a transparent view.
-                previousNotificationStart = newYTranslation + child.getClipTopAmount();
+                previousNotificationStart = newYTranslation + state.clipTopAmount;
                 previousNotificationEnd = newNotificationEnd;
                 previousNotificationIsSwiped = child.getTranslationX() != 0;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 94cb16d..1ad4acc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -160,9 +160,8 @@
                 }
 
                 if(child instanceof SpeedBumpView) {
-                    float speedBumpEnd = newYTranslation + newHeight;
-                    performSpeedBumpAnimation(i, (SpeedBumpView) child, speedBumpEnd,
-                            newYTranslation);
+                    float lineEnd = newYTranslation + newHeight / 2;
+                    performSpeedBumpAnimation(i, (SpeedBumpView) child, lineEnd);
                 }
             }
         }
@@ -183,20 +182,12 @@
         child.setClipBounds(mClipRect);
     }
 
-    private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd,
-            float speedBumpStart) {
+    private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd) {
         View nextChild = getNextChildNotGone(i);
         if (nextChild != null) {
             ViewState nextState = getViewStateForView(nextChild);
-            boolean startIsAboveNext = nextState.yTranslation > speedBumpStart;
+            boolean startIsAboveNext = nextState.yTranslation > speedBumpEnd;
             speedBump.animateDivider(startIsAboveNext, null /* onFinishedRunnable */);
-
-            // handle expanded case
-            if (speedBump.isExpanded()) {
-                boolean endIsAboveNext = nextState.yTranslation > speedBumpEnd;
-                speedBump.animateExplanationText(endIsAboveNext);
-            }
-
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index faea8de..9260aac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,14 +17,14 @@
 package com.android.systemui.statusbar.tv;
 
 import android.os.IBinder;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BaseStatusBar;
 
 /*
@@ -51,11 +51,11 @@
     }
 
     @Override
-    public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
     }
 
     @Override
-    protected void updateRankingInternal(Ranking ranking) {
+    protected void updateRankingInternal(RankingMap ranking) {
     }
 
     @Override
@@ -63,7 +63,7 @@
     }
 
     @Override
-    public void removeNotificationInternal(String key, Ranking ranking) {
+    public void removeNotificationInternal(String key, RankingMap ranking) {
     }
 
     @Override
@@ -147,6 +147,18 @@
     }
 
     @Override
+    public void scheduleHeadsUpOpen() {
+    }
+
+    @Override
+    public void scheduleHeadsUpEscalation() {
+    }
+
+    @Override
+    public void scheduleHeadsUpClose() {
+    }
+
+    @Override
     protected int getMaxKeyguardNotifications() {
         return 0;
     }
@@ -164,10 +176,10 @@
     }
 
     @Override
-    public void onActivated(View view) {
+    public void onActivated(ActivatableNotificationView view) {
     }
 
     @Override
-    public void onActivationReset(View view) {
+    public void onActivationReset(ActivatableNotificationView view) {
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index a8645bc..ef096e0 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -93,6 +93,7 @@
 import android.view.ViewRootImpl;
 import android.view.ViewStub;
 import android.view.Window;
+import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -2627,15 +2628,15 @@
         }
 
         @Override
-        protected boolean fitSystemWindows(Rect insets) {
-            mFrameOffsets.set(insets);
+        public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+            mFrameOffsets.set(insets.getSystemWindowInsets());
             updateColorViews(insets);
-            updateStatusGuard(insets);
+            insets = updateStatusGuard(insets);
             updateNavigationGuard(insets);
             if (getForeground() != null) {
                 drawableChanged();
             }
-            return super.fitSystemWindows(insets);
+            return insets;
         }
 
         @Override
@@ -2643,14 +2644,14 @@
             return false;
         }
 
-        private void updateColorViews(Rect insets) {
+        private void updateColorViews(WindowInsets insets) {
             if (mIsFloating || !ActivityManager.isHighEndGfx()) {
                 // No colors on floating windows or low end devices :(
                 return;
             }
             if (insets != null) {
-                mLastTopInset = insets.top;
-                mLastBottomInset = insets.bottom;
+                mLastTopInset = insets.getSystemWindowInsetTop();
+                mLastBottomInset = insets.getSystemWindowInsetBottom();
             }
             mStatusColorView = updateColorViewInt(mStatusColorView,
                     SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
@@ -2689,7 +2690,7 @@
             return view;
         }
 
-        private void updateStatusGuard(Rect insets) {
+        private WindowInsets updateStatusGuard(WindowInsets insets) {
             boolean showStatusGuard = false;
             // Show the status guard when the non-overlay contextual action bar is showing
             if (mActionModeView != null) {
@@ -2701,9 +2702,9 @@
                             && mActionModeView.isShown();
                     if (nonOverlayShown) {
                         // set top margin to top insets, show status guard
-                        if (mlp.topMargin != insets.top) {
+                        if (mlp.topMargin != insets.getSystemWindowInsetTop()) {
                             mlpChanged = true;
-                            mlp.topMargin = insets.top;
+                            mlp.topMargin = insets.getSystemWindowInsetTop();
                             if (mStatusGuard == null) {
                                 mStatusGuard = new View(mContext);
                                 mStatusGuard.setBackgroundColor(mContext.getResources()
@@ -2719,7 +2720,8 @@
                                 }
                             }
                         }
-                        insets.top = 0;  // consume top insets
+                        insets = insets.consumeSystemWindowInsets(
+                                false, true /* top */, false, false);
                         showStatusGuard = true;
                     } else {
                         // reset top margin
@@ -2736,9 +2738,10 @@
             if (mStatusGuard != null) {
                 mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
             }
+            return insets;
         }
 
-        private void updateNavigationGuard(Rect insets) {
+        private void updateNavigationGuard(WindowInsets insets) {
             // IMEs lay out below the nav bar, but the content view must not (for back compat)
             if (getAttributes().type == WindowManager.LayoutParams.TYPE_INPUT_METHOD) {
                 // prevent the content view from including the nav bar height
@@ -2746,7 +2749,7 @@
                     if (mContentParent.getLayoutParams() instanceof MarginLayoutParams) {
                         MarginLayoutParams mlp =
                                 (MarginLayoutParams) mContentParent.getLayoutParams();
-                        mlp.bottomMargin = insets.bottom;
+                        mlp.bottomMargin = insets.getSystemWindowInsetBottom();
                         mContentParent.setLayoutParams(mlp);
                     }
                 }
@@ -2756,11 +2759,11 @@
                     mNavigationGuard.setBackgroundColor(mContext.getResources()
                             .getColor(R.color.input_method_navigation_guard));
                     addView(mNavigationGuard, indexOfChild(mNavigationColorView), new LayoutParams(
-                            LayoutParams.MATCH_PARENT, insets.bottom,
+                            LayoutParams.MATCH_PARENT, insets.getSystemWindowInsetBottom(),
                             Gravity.START | Gravity.BOTTOM));
                 } else {
                     LayoutParams lp = (LayoutParams) mNavigationGuard.getLayoutParams();
-                    lp.height = insets.bottom;
+                    lp.height = insets.getSystemWindowInsetBottom();
                     mNavigationGuard.setLayoutParams(lp);
                 }
             }
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index fe5c2ef..aeb195f 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.database.ContentObserver;
 import android.os.BatteryStats;
 import com.android.internal.app.IBatteryStats;
 import com.android.server.am.BatteryStatsService;
@@ -149,8 +150,8 @@
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
         mLowBatteryWarningLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_lowBatteryWarningLevel);
-        mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
+        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
         mShutdownBatteryTemperature = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_shutdownBatteryTemperature);
 
@@ -173,11 +174,39 @@
     void systemReady() {
         // check our power situation now that it is safe to display the shutdown dialog.
         synchronized (mLock) {
-            shutdownIfNoPowerLocked();
-            shutdownIfOverTempLocked();
+            ContentObserver obs = new ContentObserver(mHandler) {
+                @Override
+                public void onChange(boolean selfChange) {
+                    synchronized (mLock) {
+                        updateBatteryWarningLevelLocked();
+                    }
+                }
+            };
+            final ContentResolver resolver = mContext.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+                    false, obs, UserHandle.USER_ALL);
+            updateBatteryWarningLevelLocked();
         }
     }
 
+    void updateBatteryWarningLevelLocked() {
+        final ContentResolver resolver = mContext.getContentResolver();
+        int defWarnLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryWarningLevel);
+        mLowBatteryWarningLevel = Settings.Global.getInt(resolver,
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
+        if (mLowBatteryWarningLevel == 0) {
+            mLowBatteryWarningLevel = defWarnLevel;
+        }
+        if (mLowBatteryWarningLevel < mCriticalBatteryLevel) {
+            mLowBatteryWarningLevel = mCriticalBatteryLevel;
+        }
+        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
+        processValuesLocked(true);
+    }
+
     /**
      * Returns true if the device is plugged into any of the specified plug types.
      */
@@ -232,7 +261,7 @@
         }
     }
 
-    public boolean isBatteryLowLocked() {
+    public boolean shouldSendBatteryLowLocked() {
         final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;
         final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;
 
@@ -299,14 +328,14 @@
             if (!mUpdatesStopped) {
                 mBatteryProps = props;
                 // Process the new values.
-                processValuesLocked();
+                processValuesLocked(false);
             } else {
                 mLastBatteryProps.set(props);
             }
         }
     }
 
-    private void processValuesLocked() {
+    private void processValuesLocked(boolean force) {
         boolean logOutlier = false;
         long dischargeDuration = 0;
 
@@ -349,14 +378,14 @@
         shutdownIfNoPowerLocked();
         shutdownIfOverTempLocked();
 
-        if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
+        if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
                 mBatteryProps.batteryHealth != mLastBatteryHealth ||
                 mBatteryProps.batteryPresent != mLastBatteryPresent ||
                 mBatteryProps.batteryLevel != mLastBatteryLevel ||
                 mPlugType != mLastPlugType ||
                 mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
                 mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
-                mInvalidCharger != mLastInvalidCharger) {
+                mInvalidCharger != mLastInvalidCharger)) {
 
             if (mPlugType != mLastPlugType) {
                 if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -400,7 +429,24 @@
                 logOutlier = true;
             }
 
-            mBatteryLevelLow = isBatteryLowLocked();
+            if (!mBatteryLevelLow) {
+                // Should we now switch in to low battery mode?
+                if (mPlugType == BATTERY_PLUGGED_NONE
+                        && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
+                    mBatteryLevelLow = true;
+                }
+            } else {
+                // Should we now switch out of low battery mode?
+                if (mPlugType != BATTERY_PLUGGED_NONE) {
+                    mBatteryLevelLow = false;
+                } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel)  {
+                    mBatteryLevelLow = false;
+                } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
+                    // If being forced, the previous state doesn't matter, we will just
+                    // absolutely check to see if we are now above the warning level.
+                    mBatteryLevelLow = false;
+                }
+            }
 
             sendIntentLocked();
 
@@ -428,7 +474,7 @@
                 });
             }
 
-            if (mBatteryLevelLow) {
+            if (shouldSendBatteryLowLocked()) {
                 mSentLowBatteryBroadcast = true;
                 mHandler.post(new Runnable() {
                     @Override
@@ -650,7 +696,7 @@
                         long ident = Binder.clearCallingIdentity();
                         try {
                             mUpdatesStopped = true;
-                            processValuesLocked();
+                            processValuesLocked(false);
                         } finally {
                             Binder.restoreCallingIdentity(ident);
                         }
@@ -664,7 +710,7 @@
                     if (mUpdatesStopped) {
                         mUpdatesStopped = false;
                         mBatteryProps.set(mLastBatteryProps);
-                        processValuesLocked();
+                        processValuesLocked(false);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index bd45761..e39e077 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -20,7 +20,6 @@
 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
-import static android.net.ConnectivityManager.NetworkCallbackListener;
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_DUMMY;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
@@ -630,8 +629,8 @@
         if (DBG) log("ConnectivityService starting up");
 
         NetworkCapabilities netCap = new NetworkCapabilities();
-        netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         mDefaultRequest = new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
                 NetworkRequestInfo.REQUEST);
@@ -1669,7 +1668,7 @@
                         continue;
                     }
 
-                    int prefix = destination.getNetworkPrefixLength();
+                    int prefix = destination.getPrefixLength();
                     InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix);
                     InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(),
                             prefix);
@@ -1871,7 +1870,7 @@
                             mNetd.addRoute(netId, r);
                         }
                         if (exempt) {
-                            LinkAddress dest = r.getDestination();
+                            LinkAddress dest = r.getDestinationLinkAddress();
                             if (!mExemptAddresses.contains(dest)) {
                                 mNetd.setHostExemption(dest);
                                 mExemptAddresses.add(dest);
@@ -1904,7 +1903,7 @@
                             } else {
                                 mNetd.removeRoute(netId, r);
                             }
-                            LinkAddress dest = r.getDestination();
+                            LinkAddress dest = r.getDestinationLinkAddress();
                             if (mExemptAddresses.contains(dest)) {
                                 mNetd.clearHostExemption(dest);
                                 mExemptAddresses.remove(dest);
@@ -2691,7 +2690,7 @@
             dnsDiff = curLp.compareDnses(newLp);
         } else if (newLp != null) {
             routeDiff.added = newLp.getAllRoutes();
-            dnsDiff.added = newLp.getDnses();
+            dnsDiff.added = newLp.getDnsServers();
         }
 
         boolean routesChanged = (routeDiff.removed.size() != 0 || routeDiff.added.size() != 0);
@@ -2915,7 +2914,7 @@
         if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
             LinkProperties p = nt.getLinkProperties();
             if (p == null) return;
-            Collection<InetAddress> dnses = p.getDnses();
+            Collection<InetAddress> dnses = p.getDnsServers();
             int netId = nt.getNetwork().netId;
             if (mNetConfigs[netType].isDefault()) {
                 String network = nt.getNetworkInfo().getTypeName();
@@ -5401,7 +5400,7 @@
 
     @Override
     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
-            Messenger messenger, int timeoutSec, IBinder binder, int legacyType) {
+            Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
         if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                 == false) {
             enforceConnectivityInternalPermission();
@@ -5409,7 +5408,7 @@
             enforceChangePermission();
         }
 
-        if (timeoutSec < 0 || timeoutSec > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_SEC) {
+        if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) {
             throw new IllegalArgumentException("Bad timeout specified");
         }
         NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
@@ -5419,9 +5418,9 @@
                 NetworkRequestInfo.REQUEST);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
-        if (timeoutSec > 0) {
+        if (timeoutMs > 0) {
             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
-                    nri), timeoutSec * 1000);
+                    nri), timeoutMs);
         }
         return networkRequest;
     }
@@ -5625,7 +5624,7 @@
     }
     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
         if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
-            Collection<InetAddress> dnses = newLp.getDnses();
+            Collection<InetAddress> dnses = newLp.getDnsServers();
             if (dnses.size() == 0 && mDefaultDns != null) {
                 dnses = new ArrayList();
                 dnses.add(mDefaultDns);
@@ -5685,7 +5684,7 @@
         int a2 = 0;
         switch (notificationType) {
             case ConnectivityManager.CALLBACK_LOSING:
-                a1 = 30; // TODO - read this from NetworkMonitor
+                a1 = 30 * 1000; // TODO - read this from NetworkMonitor
                 // fall through
             case ConnectivityManager.CALLBACK_PRECHECK:
             case ConnectivityManager.CALLBACK_AVAILABLE:
@@ -5790,7 +5789,8 @@
                         isNewDefault = true;
                         updateActiveDefaultNetwork(newNetwork);
                         if (newNetwork.linkProperties != null) {
-                            setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnses());
+                            setDefaultDnsSystemProperties(
+                                    newNetwork.linkProperties.getDnsServers());
                         } else {
                             setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
                         }
diff --git a/services/core/java/com/android/server/MountServiceIdler.java b/services/core/java/com/android/server/MountServiceIdler.java
index 61790826..bcb6e9e 100644
--- a/services/core/java/com/android/server/MountServiceIdler.java
+++ b/services/core/java/com/android/server/MountServiceIdler.java
@@ -18,32 +18,32 @@
 
 import java.util.Calendar;
 
-import android.app.task.Task;
-import android.app.task.TaskManager;
-import android.app.task.TaskParams;
-import android.app.task.TaskService;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
 import android.content.ComponentName;
 import android.content.Context;
 import android.util.Slog;
 
-public class MountServiceIdler extends TaskService {
+public class MountServiceIdler extends JobService {
     private static final String TAG = "MountServiceIdler";
 
     private static ComponentName sIdleService =
             new ComponentName(MountServiceIdler.class.getPackage().getName(),
                     MountServiceIdler.class.getName());
 
-    private static int MOUNT_TASK_ID = 808;
+    private static int MOUNT_JOB_ID = 808;
 
     private boolean mStarted;
-    private TaskParams mTaskParams;
+    private JobParameters mJobParams;
     private Runnable mFinishCallback = new Runnable() {
         @Override
         public void run() {
             Slog.i(TAG, "Got mount service completion callback");
             synchronized (mFinishCallback) {
                 if (mStarted) {
-                    taskFinished(mTaskParams, false);
+                    jobFinished(mJobParams, false);
                     mStarted = false;
                 }
             }
@@ -53,12 +53,12 @@
     };
 
     @Override
-    public boolean onStartTask(TaskParams params) {
+    public boolean onStartJob(JobParameters params) {
         // 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.
-        mTaskParams = params;
+        mJobParams = params;
         MountService ms = MountService.sSelf;
         if (ms != null) {
             synchronized (mFinishCallback) {
@@ -70,9 +70,9 @@
     }
 
     @Override
-    public boolean onStopTask(TaskParams params) {
+    public boolean onStopJob(JobParameters params) {
         // Once we kick off the fstrim we aren't actually interruptible; just note
-        // that we don't need to call taskFinished(), and let everything happen in
+        // that we don't need to call jobFinished(), and let everything happen in
         // the callback from the mount service.
         synchronized (mFinishCallback) {
             mStarted = false;
@@ -84,12 +84,12 @@
      * Schedule the idle job that will ping the mount service
      */
     public static void scheduleIdlePass(Context context) {
-        TaskManager tm = (TaskManager) context.getSystemService(Context.TASK_SERVICE);
+        JobScheduler tm = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
 
         Calendar calendar = tomorrowMidnight();
         final long timeToMidnight = calendar.getTimeInMillis() - System.currentTimeMillis();
 
-        Task.Builder builder = new Task.Builder(MOUNT_TASK_ID, sIdleService);
+        JobInfo.Builder builder = new JobInfo.Builder(MOUNT_JOB_ID, sIdleService);
         builder.setRequiresDeviceIdle(true);
         builder.setRequiresCharging(true);
         builder.setMinimumLatency(timeToMidnight);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index eefe8da..362061e 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -795,7 +795,7 @@
 
         final Command cmd = new Command("interface", "setcfg", iface,
                 linkAddr.getAddress().getHostAddress(),
-                linkAddr.getNetworkPrefixLength());
+                linkAddr.getPrefixLength());
         for (String flag : cfg.getFlags()) {
             cmd.appendArg(flag);
         }
@@ -882,9 +882,9 @@
         final Command cmd = new Command("network", "route", action, netId);
 
         // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
-        final LinkAddress la = route.getDestination();
+        final LinkAddress la = route.getDestinationLinkAddress();
         cmd.appendArg(route.getInterface());
-        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getNetworkPrefixLength());
+        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
         if (route.hasGateway()) {
             cmd.appendArg(route.getGateway().getHostAddress());
         }
@@ -1697,9 +1697,9 @@
     public void setMarkedForwardingRoute(String iface, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            LinkAddress dest = route.getDestination();
+            LinkAddress dest = route.getDestinationLinkAddress();
             mConnector.execute("interface", "fwmark", "route", "add", iface,
-                    dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+                    dest.getAddress().getHostAddress(), dest.getPrefixLength());
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
@@ -1709,9 +1709,9 @@
     public void clearMarkedForwardingRoute(String iface, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            LinkAddress dest = route.getDestination();
+            LinkAddress dest = route.getDestinationLinkAddress();
             mConnector.execute("interface", "fwmark", "route", "remove", iface,
-                    dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+                    dest.getAddress().getHostAddress(), dest.getPrefixLength());
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
@@ -1998,9 +1998,9 @@
         final Command cmd = new Command("network", "route", "legacy", uid, action, netId);
 
         // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
-        final LinkAddress la = routeInfo.getDestination();
+        final LinkAddress la = routeInfo.getDestinationLinkAddress();
         cmd.appendArg(routeInfo.getInterface());
-        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getNetworkPrefixLength());
+        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
         if (routeInfo.hasGateway()) {
             cmd.appendArg(routeInfo.getGateway().getHostAddress());
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 70327a6..bd1baac 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6030,6 +6030,9 @@
             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
+        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
+            return false;
+        }
 
         if (pi.applicationInfo.uid == uid) {
             return true;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b429b93..fe49371 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -906,6 +906,9 @@
             }
             startTime = 0;
             finishLaunchTickingLocked();
+            if (task != null) {
+                task.hasBeenVisible = true;
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 35f8f31..196e8609 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -45,6 +45,7 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.IActivityManager.WaitResult;
 import android.app.ResultInfo;
+import android.app.StatusBarManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IIntentSender;
@@ -73,6 +74,7 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
@@ -88,11 +90,13 @@
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.os.TransferPipe;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.server.LocalServices;
 import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
 import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.wm.WindowManagerService;
 
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -128,9 +132,15 @@
     static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
     static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
     static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
+    static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
+    static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
 
     private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
 
+    /** Status Bar Service **/
+    private IBinder mToken = new Binder();
+    private IStatusBarService mStatusBarService;
+
     // For debugging to make sure the caller when acquiring/releasing our
     // wake lock is the system process.
     static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
@@ -253,6 +263,21 @@
         mLaunchingActivity.setReferenceCounted(false);
     }
 
+    // This function returns a IStatusBarService. The value is from ServiceManager.
+    // getService and is cached.
+    private IStatusBarService getStatusBarService() {
+        synchronized (mService) {
+            if (mStatusBarService == null) {
+                mStatusBarService = IStatusBarService.Stub.asInterface(
+                    ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
+                if (mStatusBarService == null) {
+                    Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
+                }
+            }
+            return mStatusBarService;
+        }
+    }
+
     void setWindowManager(WindowManagerService wm) {
         synchronized (mService) {
             mWindowManager = wm;
@@ -2953,9 +2978,12 @@
     }
 
     void setLockTaskModeLocked(TaskRecord task) {
+        final Message lockTaskMsg = Message.obtain();
         if (task == null) {
             // Take out of lock task mode.
             mLockTaskModeTask = null;
+            lockTaskMsg.what = LOCK_TASK_END_MSG;
+            mHandler.sendMessage(lockTaskMsg);
             return;
         }
         if (isLockTaskModeViolation(task)) {
@@ -2965,6 +2993,8 @@
         mLockTaskModeTask = task;
         findTaskToMoveToFrontLocked(task, 0, null);
         resumeTopActivitiesLocked();
+        lockTaskMsg.what = LOCK_TASK_START_MSG;
+        mHandler.sendMessage(lockTaskMsg);
     }
 
     boolean isLockTaskModeViolation(TaskRecord task) {
@@ -3061,6 +3091,32 @@
                     } catch (RemoteException e) {
                     }
                 }
+                case LOCK_TASK_START_MSG: {
+                    // When lock task starts, we disable the status bars.
+                    try {
+                        if (getStatusBarService() != null) {
+                            getStatusBarService().disable
+                                (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK,
+                                mToken, mService.mContext.getPackageName());
+                        }
+                    } catch (RemoteException ex) {
+                        throw new RuntimeException(ex);
+                    }
+                    break;
+                }
+                case LOCK_TASK_END_MSG: {
+                    // When lock task ends, we enable the status bars.
+                    try {
+                       if (getStatusBarService() != null) {
+                           getStatusBarService().disable
+                               (StatusBarManager.DISABLE_NONE,
+                               mToken, mService.mContext.getPackageName());
+                       }
+                    } catch (RemoteException ex) {
+                        throw new RuntimeException(ex);
+                    }
+                    break;
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 79e2d9d..81a0b36 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -73,6 +73,7 @@
     boolean rootWasReset;   // True if the intent at the root of the task had
                             // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
     boolean askedCompatMode;// Have asked the user about compat mode for this task.
+    boolean hasBeenVisible; // Set if any activities in the task have been visible to the user.
 
     String stringName;      // caching of toString() result.
     int userId;             // user for which this task was created
@@ -328,8 +329,12 @@
     }
 
     boolean autoRemoveFromRecents() {
-        return intent != null &&
-                (intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) != 0;
+        // We will automatically remove the task either if it has explicitly asked for
+        // this, or it is empty and has never contained an activity that got shown to
+        // the user.
+        return (intent != null &&
+                (intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) != 0) ||
+                (mActivities.isEmpty() && !hasBeenVisible);
     }
 
     /**
@@ -800,7 +805,8 @@
         }
         pw.print(prefix); pw.print("lastThumbnail="); pw.print(lastThumbnail);
                 pw.print(" lastDescription="); pw.println(lastDescription);
-        pw.print(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime);
+        pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
+                pw.print(" lastActiveTime="); pw.print(lastActiveTime);
                 pw.print(" (inactive for ");
                 pw.print((getInactiveDuration()/1000)); pw.println("s)");
     }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 92b5f52..bdf4708 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1344,7 +1344,7 @@
 
                     if (iface != null) {
                         String[] dnsServers = mDefaultDnsServers;
-                        Collection<InetAddress> dnses = linkProperties.getDnses();
+                        Collection<InetAddress> dnses = linkProperties.getDnsServers();
                         if (dnses != null) {
                             // we currently only handle IPv4
                             ArrayList<InetAddress> v4Dnses =
diff --git a/services/core/java/com/android/server/task/TaskCompletedListener.java b/services/core/java/com/android/server/job/JobCompletedListener.java
similarity index 62%
rename from services/core/java/com/android/server/task/TaskCompletedListener.java
rename to services/core/java/com/android/server/job/JobCompletedListener.java
index c53f5ca..a7af9cd 100644
--- a/services/core/java/com/android/server/task/TaskCompletedListener.java
+++ b/services/core/java/com/android/server/job/JobCompletedListener.java
@@ -14,19 +14,19 @@
  * limitations under the License
  */
 
-package com.android.server.task;
+package com.android.server.job;
 
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.controllers.JobStatus;
 
 /**
- * Used for communication between {@link com.android.server.task.TaskServiceContext} and the
- * {@link com.android.server.task.TaskManagerService}.
+ * Used for communication between {@link com.android.server.job.JobServiceContext} and the
+ * {@link com.android.server.job.JobSchedulerService}.
  */
-public interface TaskCompletedListener {
+public interface JobCompletedListener {
 
     /**
-     * Callback for when a task is completed.
-     * @param needsReschedule Whether the implementing class should reschedule this task.
+     * Callback for when a job is completed.
+     * @param needsReschedule Whether the implementing class should reschedule this job.
      */
-    public void onTaskCompleted(TaskStatus taskStatus, boolean needsReschedule);
+    public void onJobCompleted(JobStatus jobStatus, boolean needsReschedule);
 }
diff --git a/services/core/java/com/android/server/task/TaskMapReadFinishedListener.java b/services/core/java/com/android/server/job/JobMapReadFinishedListener.java
similarity index 68%
rename from services/core/java/com/android/server/task/TaskMapReadFinishedListener.java
rename to services/core/java/com/android/server/job/JobMapReadFinishedListener.java
index c68d8db..f3e77e6 100644
--- a/services/core/java/com/android/server/task/TaskMapReadFinishedListener.java
+++ b/services/core/java/com/android/server/job/JobMapReadFinishedListener.java
@@ -14,21 +14,21 @@
  * limitations under the License
  */
 
-package com.android.server.task;
+package com.android.server.job;
 
 import java.util.List;
 
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.controllers.JobStatus;
 
 /**
- * Callback definition for I/O thread to let the TaskManagerService know when
+ * Callback definition for I/O thread to let the JobManagerService know when
  * I/O read has completed. Done this way so we don't stall the main thread on
  * boot.
  */
-public interface TaskMapReadFinishedListener {
+public interface JobMapReadFinishedListener {
 
     /**
-     * Called by the {@link TaskStore} at boot, when the disk read is finished.
+     * Called by the {@link JobStore} at boot, when the disk read is finished.
      */
-    public void onTaskMapReadFinished(List<TaskStatus> tasks);
+    public void onJobMapReadFinished(List<JobStatus> jobs);
 }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
new file mode 100644
index 0000000..0e9a9cc
--- /dev/null
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -0,0 +1,764 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.app.job.IJobScheduler;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.server.job.controllers.BatteryController;
+import com.android.server.job.controllers.ConnectivityController;
+import com.android.server.job.controllers.IdleController;
+import com.android.server.job.controllers.JobStatus;
+import com.android.server.job.controllers.StateController;
+import com.android.server.job.controllers.TimeController;
+
+import java.util.LinkedList;
+
+/**
+ * Responsible for taking jobs representing work to be performed by a client app, and determining
+ * based on the criteria specified when that job should be run against the client application's
+ * endpoint.
+ * Implements logic for scheduling, and rescheduling jobs. The JobSchedulerService knows nothing
+ * about constraints, or the state of active jobs. It receives callbacks from the various
+ * controllers and completed jobs and operates accordingly.
+ *
+ * Note on locking: Any operations that manipulate {@link #mJobs} need to lock on that object.
+ * Any function with the suffix 'Locked' also needs to lock on {@link #mJobs}.
+ * @hide
+ */
+public class JobSchedulerService extends com.android.server.SystemService
+        implements StateChangedListener, JobCompletedListener, JobMapReadFinishedListener {
+    // TODO: Switch this off for final version.
+    static final boolean DEBUG = true;
+    /** The number of concurrent jobs we run at one time. */
+    private static final int MAX_JOB_CONTEXTS_COUNT = 3;
+    static final String TAG = "JobManagerService";
+    /** Master list of jobs. */
+    private final JobStore mJobs;
+
+    static final int MSG_JOB_EXPIRED = 0;
+    static final int MSG_CHECK_JOB = 1;
+
+    // Policy constants
+    /**
+     * Minimum # of idle jobs that must be ready in order to force the JMS to schedule things
+     * early.
+     */
+    private static final int MIN_IDLE_COUNT = 1;
+    /**
+     * Minimum # of connectivity jobs that must be ready in order to force the JMS to schedule
+     * things early.
+     */
+    private static final int MIN_CONNECTIVITY_COUNT = 2;
+    /**
+     * Minimum # of jobs (with no particular constraints) for which the JMS will be happy running
+     * some work early.
+     */
+    private static final int MIN_READY_JOBS_COUNT = 4;
+
+    /**
+     * Track Services that have currently active or pending jobs. The index is provided by
+     * {@link JobStatus#getServiceToken()}
+     */
+    private final List<JobServiceContext> mActiveServices = new LinkedList<JobServiceContext>();
+    /** List of controllers that will notify this service of updates to jobs. */
+    private List<StateController> mControllers;
+    /**
+     * Queue of pending jobs. The JobServiceContext class will receive jobs from this list
+     * when ready to execute them.
+     */
+    private final LinkedList<JobStatus> mPendingJobs = new LinkedList<JobStatus>();
+
+    private final JobHandler mHandler;
+    private final JobSchedulerStub mJobSchedulerStub;
+    /**
+     * Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we
+     * still clean up. On reinstall the package will have a new uid.
+     */
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Slog.d(TAG, "Receieved: " + intent.getAction());
+            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+                int uidRemoved = intent.getIntExtra(Intent.EXTRA_UID, -1);
+                if (DEBUG) {
+                    Slog.d(TAG, "Removing jobs for uid: " + uidRemoved);
+                }
+                cancelJobsForUid(uidRemoved);
+            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (DEBUG) {
+                    Slog.d(TAG, "Removing jobs for user: " + userId);
+                }
+                cancelJobsForUser(userId);
+            }
+        }
+    };
+
+    /**
+     * Entry point from client to schedule the provided job.
+     * This cancels the job if it's already been scheduled, and replaces it with the one provided.
+     * @param job JobInfo object containing execution parameters
+     * @param uId The package identifier of the application this job is for.
+     * @param canPersistJob Whether or not the client has the appropriate permissions for
+     *                       persisting this job.
+     * @return Result of this operation. See <code>JobScheduler#RESULT_*</code> return codes.
+     */
+    public int schedule(JobInfo job, int uId, boolean canPersistJob) {
+        JobStatus jobStatus = new JobStatus(job, uId, canPersistJob);
+        cancelJob(uId, job.getId());
+        startTrackingJob(jobStatus);
+        return JobScheduler.RESULT_SUCCESS;
+    }
+
+    public List<JobInfo> getPendingJobs(int uid) {
+        ArrayList<JobInfo> outList = new ArrayList<JobInfo>();
+        synchronized (mJobs) {
+            for (JobStatus job : mJobs.getJobs()) {
+                if (job.getUid() == uid) {
+                    outList.add(job.getJob());
+                }
+            }
+        }
+        return outList;
+    }
+
+    private void cancelJobsForUser(int userHandle) {
+        synchronized (mJobs) {
+            List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle);
+            for (JobStatus toRemove : jobsForUser) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Cancelling: " + toRemove);
+                }
+                cancelJobLocked(toRemove);
+            }
+        }
+    }
+
+    /**
+     * Entry point from client to cancel all jobs originating from their uid.
+     * This will remove the job from the master list, and cancel the job if it was staged for
+     * execution or being executed.
+     * @param uid To check against for removal of a job.
+     */
+    public void cancelJobsForUid(int uid) {
+        // Remove from master list.
+        synchronized (mJobs) {
+            List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
+            for (JobStatus toRemove : jobsForUid) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Cancelling: " + toRemove);
+                }
+                cancelJobLocked(toRemove);
+            }
+        }
+    }
+
+    /**
+     * Entry point from client to cancel the job corresponding to the jobId provided.
+     * This will remove the job from the master list, and cancel the job if it was staged for
+     * execution or being executed.
+     * @param uid Uid of the calling client.
+     * @param jobId Id of the job, provided at schedule-time.
+     */
+    public void cancelJob(int uid, int jobId) {
+        JobStatus toCancel;
+        synchronized (mJobs) {
+            toCancel = mJobs.getJobByUidAndJobId(uid, jobId);
+            if (toCancel != null) {
+                cancelJobLocked(toCancel);
+            }
+        }
+    }
+
+    private void cancelJobLocked(JobStatus cancelled) {
+        // Remove from store.
+        stopTrackingJob(cancelled);
+        // Remove from pending queue.
+        mPendingJobs.remove(cancelled);
+        // Cancel if running.
+        stopJobOnServiceContextLocked(cancelled);
+    }
+
+    /**
+     * Initializes the system service.
+     * <p>
+     * Subclasses must define a single argument constructor that accepts the context
+     * and passes it to super.
+     * </p>
+     *
+     * @param context The system server context.
+     */
+    public JobSchedulerService(Context context) {
+        super(context);
+        // Create the controllers.
+        mControllers = new LinkedList<StateController>();
+        mControllers.add(ConnectivityController.get(this));
+        mControllers.add(TimeController.get(this));
+        mControllers.add(IdleController.get(this));
+        mControllers.add(BatteryController.get(this));
+
+        mHandler = new JobHandler(context.getMainLooper());
+        mJobSchedulerStub = new JobSchedulerStub();
+        // Create the "runners".
+        for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
+            mActiveServices.add(
+                    new JobServiceContext(this, context.getMainLooper()));
+        }
+        mJobs = JobStore.initAndGet(this);
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.JOB_SCHEDULER_SERVICE, mJobSchedulerStub);
+    }
+
+    @Override
+    public void onBootPhase(int phase) {
+        if (PHASE_SYSTEM_SERVICES_READY == phase) {
+            // Register br for package removals and user removals.
+            final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+            filter.addDataScheme("package");
+            getContext().registerReceiverAsUser(
+                    mBroadcastReceiver, UserHandle.ALL, filter, null, null);
+            final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED);
+            getContext().registerReceiverAsUser(
+                    mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);
+        }
+    }
+
+    /**
+     * Called when we have a job status object that we need to insert in our
+     * {@link com.android.server.job.JobStore}, and make sure all the relevant controllers know
+     * about.
+     */
+    private void startTrackingJob(JobStatus jobStatus) {
+        boolean update;
+        synchronized (mJobs) {
+            update = mJobs.add(jobStatus);
+        }
+        for (StateController controller : mControllers) {
+            if (update) {
+                controller.maybeStopTrackingJob(jobStatus);
+            }
+            controller.maybeStartTrackingJob(jobStatus);
+        }
+    }
+
+    /**
+     * Called when we want to remove a JobStatus object that we've finished executing. Returns the
+     * object removed.
+     */
+    private boolean stopTrackingJob(JobStatus jobStatus) {
+        boolean removed;
+        synchronized (mJobs) {
+            // Remove from store as well as controllers.
+            removed = mJobs.remove(jobStatus);
+        }
+        if (removed) {
+            for (StateController controller : mControllers) {
+                controller.maybeStopTrackingJob(jobStatus);
+            }
+        }
+        return removed;
+    }
+
+    private boolean stopJobOnServiceContextLocked(JobStatus job) {
+        for (JobServiceContext jsc : mActiveServices) {
+            final JobStatus executing = jsc.getRunningJob();
+            if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
+                jsc.cancelExecutingJob();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param job JobStatus we are querying against.
+     * @return Whether or not the job represented by the status object is currently being run or
+     * is pending.
+     */
+    private boolean isCurrentlyActiveLocked(JobStatus job) {
+        for (JobServiceContext serviceContext : mActiveServices) {
+            final JobStatus running = serviceContext.getRunningJob();
+            if (running != null && running.matches(job.getUid(), job.getJobId())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * A job is rescheduled with exponential back-off if the client requests this from their
+     * execution logic.
+     * A caveat is for idle-mode jobs, for which the idle-mode constraint will usurp the
+     * timeliness of the reschedule. For an idle-mode job, no deadline is given.
+     * @param failureToReschedule Provided job status that we will reschedule.
+     * @return A newly instantiated JobStatus with the same constraints as the last job except
+     * with adjusted timing constraints.
+     */
+    private JobStatus getRescheduleJobForFailure(JobStatus failureToReschedule) {
+        final long elapsedNowMillis = SystemClock.elapsedRealtime();
+        final JobInfo job = failureToReschedule.getJob();
+
+        final long initialBackoffMillis = job.getInitialBackoffMillis();
+        final int backoffAttempt = failureToReschedule.getNumFailures() + 1;
+        long newEarliestRuntimeElapsed = elapsedNowMillis;
+
+        switch (job.getBackoffPolicy()) {
+            case JobInfo.BackoffPolicy.LINEAR:
+                newEarliestRuntimeElapsed += initialBackoffMillis * backoffAttempt;
+                break;
+            default:
+                if (DEBUG) {
+                    Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential.");
+                }
+            case JobInfo.BackoffPolicy.EXPONENTIAL:
+                newEarliestRuntimeElapsed +=
+                        Math.pow(initialBackoffMillis * 0.001, backoffAttempt) * 1000;
+                break;
+        }
+        newEarliestRuntimeElapsed =
+                Math.min(newEarliestRuntimeElapsed, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
+        return new JobStatus(failureToReschedule, newEarliestRuntimeElapsed,
+                JobStatus.NO_LATEST_RUNTIME, backoffAttempt);
+    }
+
+    /**
+     * Called after a periodic has executed so we can to re-add it. We take the last execution time
+     * of the job to be the time of completion (i.e. the time at which this function is called).
+     * This could be inaccurate b/c the job can run for as long as
+     * {@link com.android.server.job.JobServiceContext#EXECUTING_TIMESLICE_MILLIS}, but will lead
+     * to underscheduling at least, rather than if we had taken the last execution time to be the
+     * start of the execution.
+     * @return A new job representing the execution criteria for this instantiation of the
+     * recurring job.
+     */
+    private JobStatus getRescheduleJobForPeriodic(JobStatus periodicToReschedule) {
+        final long elapsedNow = SystemClock.elapsedRealtime();
+        // Compute how much of the period is remaining.
+        long runEarly = Math.max(periodicToReschedule.getLatestRunTimeElapsed() - elapsedNow, 0);
+        long newEarliestRunTimeElapsed = elapsedNow + runEarly;
+        long period = periodicToReschedule.getJob().getIntervalMillis();
+        long newLatestRuntimeElapsed = newEarliestRunTimeElapsed + period;
+
+        if (DEBUG) {
+            Slog.v(TAG, "Rescheduling executed periodic. New execution window [" +
+                    newEarliestRunTimeElapsed/1000 + ", " + newLatestRuntimeElapsed/1000 + "]s");
+        }
+        return new JobStatus(periodicToReschedule, newEarliestRunTimeElapsed,
+                newLatestRuntimeElapsed, 0 /* backoffAttempt */);
+    }
+
+    // JobCompletedListener implementations.
+
+    /**
+     * A job just finished executing. We fetch the
+     * {@link com.android.server.job.controllers.JobStatus} from the store and depending on
+     * whether we want to reschedule we readd it to the controllers.
+     * @param jobStatus Completed job.
+     * @param needsReschedule Whether the implementing class should reschedule this job.
+     */
+    @Override
+    public void onJobCompleted(JobStatus jobStatus, boolean needsReschedule) {
+        if (DEBUG) {
+            Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
+        }
+        if (!stopTrackingJob(jobStatus)) {
+            if (DEBUG) {
+                Slog.e(TAG, "Error removing job: could not find job to remove. Was job " +
+                        "removed while executing?");
+            }
+            return;
+        }
+        if (needsReschedule) {
+            JobStatus rescheduled = getRescheduleJobForFailure(jobStatus);
+            startTrackingJob(rescheduled);
+        } else if (jobStatus.getJob().isPeriodic()) {
+            JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
+            startTrackingJob(rescheduledPeriodic);
+        }
+        mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+    }
+
+    // StateChangedListener implementations.
+
+    /**
+     * Off-board work to our handler thread as quickly as possible, b/c this call is probably being
+     * made on the main thread.
+     * For now this takes the job and if it's ready to run it will run it. In future we might not
+     * provide the job, so that the StateChangedListener has to run through its list of jobs to
+     * see which are ready. This will further decouple the controllers from the execution logic.
+     */
+    @Override
+    public void onControllerStateChanged() {
+        // Post a message to to run through the list of jobs and start/stop any that are eligible.
+        mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+    }
+
+    @Override
+    public void onRunJobNow(JobStatus jobStatus) {
+        mHandler.obtainMessage(MSG_JOB_EXPIRED, jobStatus).sendToTarget();
+    }
+
+    /**
+     * Disk I/O is finished, take the list of jobs we read from disk and add them to our
+     * {@link JobStore}.
+     * This is run on the {@link com.android.server.IoThread} instance, which is a separate thread,
+     * and is called once at boot.
+     */
+    @Override
+    public void onJobMapReadFinished(List<JobStatus> jobs) {
+        synchronized (mJobs) {
+            for (JobStatus js : jobs) {
+                if (mJobs.containsJobIdForUid(js.getJobId(), js.getUid())) {
+                    // An app with BOOT_COMPLETED *might* have decided to reschedule their job, in
+                    // the same amount of time it took us to read it from disk. If this is the case
+                    // we leave it be.
+                    continue;
+                }
+                startTrackingJob(js);
+            }
+        }
+    }
+
+    private class JobHandler extends Handler {
+
+        public JobHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_JOB_EXPIRED:
+                    synchronized (mJobs) {
+                        JobStatus runNow = (JobStatus) message.obj;
+                        if (!mPendingJobs.contains(runNow)) {
+                            mPendingJobs.add(runNow);
+                        }
+                    }
+                    queueReadyJobsForExecutionH();
+                    break;
+                case MSG_CHECK_JOB:
+                    // Check the list of jobs and run some of them if we feel inclined.
+                    maybeQueueReadyJobsForExecutionH();
+                    break;
+            }
+            maybeRunPendingJobsH();
+            // Don't remove JOB_EXPIRED in case one came along while processing the queue.
+            removeMessages(MSG_CHECK_JOB);
+        }
+
+        /**
+         * Run through list of jobs and execute all possible - at least one is expired so we do
+         * as many as we can.
+         */
+        private void queueReadyJobsForExecutionH() {
+            synchronized (mJobs) {
+                for (JobStatus job : mJobs.getJobs()) {
+                    if (isReadyToBeExecutedLocked(job)) {
+                        mPendingJobs.add(job);
+                    } else if (isReadyToBeCancelledLocked(job)) {
+                        stopJobOnServiceContextLocked(job);
+                    }
+                }
+            }
+        }
+
+        /**
+         * The state of at least one job has changed. Here is where we could enforce various
+         * policies on when we want to execute jobs.
+         * Right now the policy is such:
+         * If >1 of the ready jobs is idle mode we send all of them off
+         * if more than 2 network connectivity jobs are ready we send them all off.
+         * If more than 4 jobs total are ready we send them all off.
+         * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
+         */
+        private void maybeQueueReadyJobsForExecutionH() {
+            synchronized (mJobs) {
+                int idleCount = 0;
+                int backoffCount = 0;
+                int connectivityCount = 0;
+                List<JobStatus> runnableJobs = new ArrayList<JobStatus>();
+                for (JobStatus job : mJobs.getJobs()) {
+                    if (isReadyToBeExecutedLocked(job)) {
+                        if (job.getNumFailures() > 0) {
+                            backoffCount++;
+                        }
+                        if (job.hasIdleConstraint()) {
+                            idleCount++;
+                        }
+                        if (job.hasConnectivityConstraint() || job.hasUnmeteredConstraint()) {
+                            connectivityCount++;
+                        }
+                        runnableJobs.add(job);
+                    } else if (isReadyToBeCancelledLocked(job)) {
+                        stopJobOnServiceContextLocked(job);
+                    }
+                }
+                if (backoffCount > 0 || idleCount >= MIN_IDLE_COUNT ||
+                        connectivityCount >= MIN_CONNECTIVITY_COUNT ||
+                        runnableJobs.size() >= MIN_READY_JOBS_COUNT) {
+                    for (JobStatus job : runnableJobs) {
+                        mPendingJobs.add(job);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Criteria for moving a job into the pending queue:
+         *      - It's ready.
+         *      - It's not pending.
+         *      - It's not already running on a JSC.
+         */
+        private boolean isReadyToBeExecutedLocked(JobStatus job) {
+              return job.isReady() && !mPendingJobs.contains(job) && !isCurrentlyActiveLocked(job);
+        }
+
+        /**
+         * Criteria for cancelling an active job:
+         *      - It's not ready
+         *      - It's running on a JSC.
+         */
+        private boolean isReadyToBeCancelledLocked(JobStatus job) {
+            return !job.isReady() && isCurrentlyActiveLocked(job);
+        }
+
+        /**
+         * Reconcile jobs in the pending queue against available execution contexts.
+         * A controller can force a job into the pending queue even if it's already running, but
+         * here is where we decide whether to actually execute it.
+         */
+        private void maybeRunPendingJobsH() {
+            synchronized (mJobs) {
+                Iterator<JobStatus> it = mPendingJobs.iterator();
+                while (it.hasNext()) {
+                    JobStatus nextPending = it.next();
+                    JobServiceContext availableContext = null;
+                    for (JobServiceContext jsc : mActiveServices) {
+                        final JobStatus running = jsc.getRunningJob();
+                        if (running != null && running.matches(nextPending.getUid(),
+                                nextPending.getJobId())) {
+                            // Already running this tId for this uId, skip.
+                            availableContext = null;
+                            break;
+                        }
+                        if (jsc.isAvailable()) {
+                            availableContext = jsc;
+                        }
+                    }
+                    if (availableContext != null) {
+                        if (!availableContext.executeRunnableJob(nextPending)) {
+                            if (DEBUG) {
+                                Slog.d(TAG, "Error executing " + nextPending);
+                            }
+                            mJobs.remove(nextPending);
+                        }
+                        it.remove();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Binder stub trampoline implementation
+     */
+    final class JobSchedulerStub extends IJobScheduler.Stub {
+        /** Cache determination of whether a given app can persist jobs
+         * key is uid of the calling app; value is undetermined/true/false
+         */
+        private final SparseArray<Boolean> mPersistCache = new SparseArray<Boolean>();
+
+        // Enforce that only the app itself (or shared uid participant) can schedule a
+        // job that runs one of the app's services, as well as verifying that the
+        // named service properly requires the BIND_JOB_SERVICE permission
+        private void enforceValidJobRequest(int uid, JobInfo job) {
+            final PackageManager pm = getContext().getPackageManager();
+            final ComponentName service = job.getService();
+            try {
+                ServiceInfo si = pm.getServiceInfo(service, 0);
+                if (si.applicationInfo.uid != uid) {
+                    throw new IllegalArgumentException("uid " + uid +
+                            " cannot schedule job in " + service.getPackageName());
+                }
+                if (!JobService.PERMISSION_BIND.equals(si.permission)) {
+                    throw new IllegalArgumentException("Scheduled service " + service
+                            + " does not require android.permission.BIND_JOB_SERVICE permission");
+                }
+            } catch (NameNotFoundException e) {
+                throw new IllegalArgumentException("No such service: " + service);
+            }
+        }
+
+        private boolean canPersistJobs(int pid, int uid) {
+            // If we get this far we're good to go; all we need to do now is check
+            // whether the app is allowed to persist its scheduled work.
+            final boolean canPersist;
+            synchronized (mPersistCache) {
+                Boolean cached = mPersistCache.get(uid);
+                if (cached != null) {
+                    canPersist = cached.booleanValue();
+                } else {
+                    // Persisting jobs is tantamount to running at boot, so we permit
+                    // it when the app has declared that it uses the RECEIVE_BOOT_COMPLETED
+                    // permission
+                    int result = getContext().checkPermission(
+                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED, pid, uid);
+                    canPersist = (result == PackageManager.PERMISSION_GRANTED);
+                    mPersistCache.put(uid, canPersist);
+                }
+            }
+            return canPersist;
+        }
+
+        // IJobScheduler implementation
+        @Override
+        public int schedule(JobInfo job) throws RemoteException {
+            if (DEBUG) {
+                Slog.d(TAG, "Scheduling job: " + job);
+            }
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+
+            enforceValidJobRequest(uid, job);
+            final boolean canPersist = canPersistJobs(pid, uid);
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return JobSchedulerService.this.schedule(job, uid, canPersist);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public List<JobInfo> getAllPendingJobs() throws RemoteException {
+            final int uid = Binder.getCallingUid();
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return JobSchedulerService.this.getPendingJobs(uid);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public void cancelAll() throws RemoteException {
+            final int uid = Binder.getCallingUid();
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                JobSchedulerService.this.cancelJobsForUid(uid);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public void cancel(int jobId) throws RemoteException {
+            final int uid = Binder.getCallingUid();
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                JobSchedulerService.this.cancelJob(uid, jobId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        /**
+         * "dumpsys" infrastructure
+         */
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
+            long identityToken = Binder.clearCallingIdentity();
+            try {
+                JobSchedulerService.this.dumpInternal(pw);
+            } finally {
+                Binder.restoreCallingIdentity(identityToken);
+            }
+        }
+    };
+
+    void dumpInternal(PrintWriter pw) {
+        synchronized (mJobs) {
+            pw.println("Registered jobs:");
+            if (mJobs.size() > 0) {
+                for (JobStatus job : mJobs.getJobs()) {
+                    job.dump(pw, "  ");
+                }
+            } else {
+                pw.println();
+                pw.println("No jobs scheduled.");
+            }
+            for (StateController controller : mControllers) {
+                pw.println();
+                controller.dumpControllerState(pw);
+            }
+            pw.println();
+            pw.println("Pending");
+            for (JobStatus jobStatus : mPendingJobs) {
+                pw.println(jobStatus.hashCode());
+            }
+            pw.println();
+            pw.println("Active jobs:");
+            for (JobServiceContext jsc : mActiveServices) {
+                if (jsc.isAvailable()) {
+                    continue;
+                } else {
+                    pw.println(jsc.getRunningJob().hashCode() + " for: " +
+                            (SystemClock.elapsedRealtime()
+                                    - jsc.getExecutionStartTimeElapsed())/1000 + "s " +
+                            "timeout: " + jsc.getTimeoutElapsed());
+                }
+            }
+        }
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/task/TaskServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
similarity index 66%
rename from services/core/java/com/android/server/task/TaskServiceContext.java
rename to services/core/java/com/android/server/job/JobServiceContext.java
index a21de88..534faba3 100644
--- a/services/core/java/com/android/server/task/TaskServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -14,12 +14,12 @@
  * limitations under the License
  */
 
-package com.android.server.task;
+package com.android.server.job;
 
 import android.app.ActivityManager;
-import android.app.task.ITaskCallback;
-import android.app.task.ITaskService;
-import android.app.task.TaskParams;
+import android.app.job.JobParameters;
+import android.app.job.IJobCallback;
+import android.app.job.IJobService;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -39,32 +39,32 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.controllers.JobStatus;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * Handles client binding and lifecycle of a task. A task will only execute one at a time on an
+ * Handles client binding and lifecycle of a job. A job will only execute one at a time on an
  * instance of this class.
  */
-public class TaskServiceContext extends ITaskCallback.Stub implements ServiceConnection {
+public class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {
     private static final boolean DEBUG = true;
-    private static final String TAG = "TaskServiceContext";
-    /** Define the maximum # of tasks allowed to run on a service at once. */
-    private static final int defaultMaxActiveTasksPerService =
+    private static final String TAG = "JobServiceContext";
+    /** Define the maximum # of jobs allowed to run on a service at once. */
+    private static final int defaultMaxActiveJobsPerService =
             ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
-    /** Amount of time a task is allowed to execute for before being considered timed-out. */
+    /** Amount of time a job is allowed to execute for before being considered timed-out. */
     private static final long EXECUTING_TIMESLICE_MILLIS = 60 * 1000;
-    /** Amount of time the TaskManager will wait for a response from an app for a message. */
+    /** Amount of time the JobScheduler will wait for a response from an app for a message. */
     private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
     /** String prefix for all wakelock names. */
-    private static final String TM_WAKELOCK_PREFIX = "*task*/";
+    private static final String JS_WAKELOCK_PREFIX = "*job*/";
 
     private static final String[] VERB_STRINGS = {
             "VERB_STARTING", "VERB_EXECUTING", "VERB_STOPPING", "VERB_PENDING"
     };
 
-    // States that a task occupies while interacting with the client.
+    // States that a job occupies while interacting with the client.
     static final int VERB_BINDING = 0;
     static final int VERB_STARTING = 1;
     static final int VERB_EXECUTING = 2;
@@ -75,30 +75,30 @@
     private static final int MSG_TIMEOUT = 0;
     /** Received a callback from client. */
     private static final int MSG_CALLBACK = 1;
-    /** Run through list and start any ready tasks.*/
+    /** Run through list and start any ready jobs.*/
     private static final int MSG_SERVICE_BOUND = 2;
-    /** Cancel a task. */
+    /** Cancel a job. */
     private static final int MSG_CANCEL = 3;
-    /** Shutdown the Task. Used when the client crashes and we can't die gracefully.*/
+    /** Shutdown the job. Used when the client crashes and we can't die gracefully.*/
     private static final int MSG_SHUTDOWN_EXECUTION = 4;
 
     private final Handler mCallbackHandler;
-    /** Make callbacks to {@link TaskManagerService} to inform on task completion status. */
-    private final TaskCompletedListener mCompletedListener;
+    /** Make callbacks to {@link JobSchedulerService} to inform on job completion status. */
+    private final JobCompletedListener mCompletedListener;
     /** Used for service binding, etc. */
     private final Context mContext;
     private PowerManager.WakeLock mWakeLock;
 
     // Execution state.
-    private TaskParams mParams;
+    private JobParameters mParams;
     @VisibleForTesting
     int mVerb;
     private AtomicBoolean mCancelled = new AtomicBoolean();
 
-    /** All the information maintained about the task currently being executed. */
-    private TaskStatus mRunningTask;
+    /** All the information maintained about the job currently being executed. */
+    private JobStatus mRunningJob;
     /** Binder to the client service. */
-    ITaskService service;
+    IJobService service;
 
     private final Object mLock = new Object();
     /** Whether this context is free. */
@@ -109,45 +109,45 @@
     /** Track when job will timeout. */
     private long mTimeoutElapsed;
 
-    TaskServiceContext(TaskManagerService service, Looper looper) {
+    JobServiceContext(JobSchedulerService service, Looper looper) {
         this(service.getContext(), service, looper);
     }
 
     @VisibleForTesting
-    TaskServiceContext(Context context, TaskCompletedListener completedListener, Looper looper) {
+    JobServiceContext(Context context, JobCompletedListener completedListener, Looper looper) {
         mContext = context;
-        mCallbackHandler = new TaskServiceHandler(looper);
+        mCallbackHandler = new JobServiceHandler(looper);
         mCompletedListener = completedListener;
         mAvailable = true;
     }
 
     /**
-     * Give a task to this context for execution. Callers must first check {@link #isAvailable()}
+     * Give a job to this context for execution. Callers must first check {@link #isAvailable()}
      * to make sure this is a valid context.
-     * @param ts The status of the task that we are going to run.
-     * @return True if the task is valid and is running. False if the task cannot be executed.
+     * @param job The status of the job that we are going to run.
+     * @return True if the job is valid and is running. False if the job cannot be executed.
      */
-    boolean executeRunnableTask(TaskStatus ts) {
+    boolean executeRunnableJob(JobStatus job) {
         synchronized (mLock) {
             if (!mAvailable) {
                 Slog.e(TAG, "Starting new runnable but context is unavailable > Error.");
                 return false;
             }
 
-            mRunningTask = ts;
-            mParams = new TaskParams(ts.getTaskId(), ts.getExtras(), this);
+            mRunningJob = job;
+            mParams = new JobParameters(job.getJobId(), job.getExtras(), this);
             mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
 
             mVerb = VERB_BINDING;
-            final Intent intent = new Intent().setComponent(ts.getServiceComponent());
+            final Intent intent = new Intent().setComponent(job.getServiceComponent());
             boolean binding = mContext.bindServiceAsUser(intent, this,
                     Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND,
-                    new UserHandle(ts.getUserId()));
+                    new UserHandle(job.getUserId()));
             if (!binding) {
                 if (DEBUG) {
-                    Slog.d(TAG, ts.getServiceComponent().getShortClassName() + " unavailable.");
+                    Slog.d(TAG, job.getServiceComponent().getShortClassName() + " unavailable.");
                 }
-                mRunningTask = null;
+                mRunningJob = null;
                 mParams = null;
                 mExecutionStartTimeElapsed = 0L;
                 return false;
@@ -157,13 +157,13 @@
         }
     }
 
-    /** Used externally to query the running task. Will return null if there is no task running. */
-    TaskStatus getRunningTask() {
-        return mRunningTask;
+    /** Used externally to query the running job. Will return null if there is no job running. */
+    JobStatus getRunningJob() {
+        return mRunningJob;
     }
 
-    /** Called externally when a task that was scheduled for execution should be cancelled. */
-    void cancelExecutingTask() {
+    /** Called externally when a job that was scheduled for execution should be cancelled. */
+    void cancelExecutingJob() {
         mCallbackHandler.obtainMessage(MSG_CANCEL).sendToTarget();
     }
 
@@ -185,29 +185,29 @@
     }
 
     @Override
-    public void taskFinished(int taskId, boolean reschedule) {
+    public void jobFinished(int jobId, boolean reschedule) {
         if (!verifyCallingUid()) {
             return;
         }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, taskId, reschedule ? 1 : 0)
+        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, reschedule ? 1 : 0)
                 .sendToTarget();
     }
 
     @Override
-    public void acknowledgeStopMessage(int taskId, boolean reschedule) {
+    public void acknowledgeStopMessage(int jobId, boolean reschedule) {
         if (!verifyCallingUid()) {
             return;
         }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, taskId, reschedule ? 1 : 0)
+        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, reschedule ? 1 : 0)
                 .sendToTarget();
     }
 
     @Override
-    public void acknowledgeStartMessage(int taskId, boolean ongoing) {
+    public void acknowledgeStartMessage(int jobId, boolean ongoing) {
         if (!verifyCallingUid()) {
             return;
         }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, taskId, ongoing ? 1 : 0).sendToTarget();
+        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, ongoing ? 1 : 0).sendToTarget();
     }
 
     /**
@@ -219,25 +219,25 @@
      */
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
-        if (!name.equals(mRunningTask.getServiceComponent())) {
+        if (!name.equals(mRunningJob.getServiceComponent())) {
             mCallbackHandler.obtainMessage(MSG_SHUTDOWN_EXECUTION).sendToTarget();
             return;
         }
-        this.service = ITaskService.Stub.asInterface(service);
+        this.service = IJobService.Stub.asInterface(service);
         // Remove all timeouts.
         mCallbackHandler.removeMessages(MSG_TIMEOUT);
         final PowerManager pm =
                 (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                TM_WAKELOCK_PREFIX + mRunningTask.getServiceComponent().getPackageName());
-        mWakeLock.setWorkSource(new WorkSource(mRunningTask.getUid()));
+                JS_WAKELOCK_PREFIX + mRunningJob.getServiceComponent().getPackageName());
+        mWakeLock.setWorkSource(new WorkSource(mRunningJob.getUid()));
         mWakeLock.setReferenceCounted(false);
         mWakeLock.acquire();
         mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
     }
 
     /**
-     * If the client service crashes we reschedule this task and clean up.
+     * If the client service crashes we reschedule this job and clean up.
      * @param name The concrete component name of the service whose
      */
     @Override
@@ -251,7 +251,7 @@
      * @return True if the binder calling is coming from the client we expect.
      */
     private boolean verifyCallingUid() {
-        if (mRunningTask == null || Binder.getCallingUid() != mRunningTask.getUid()) {
+        if (mRunningJob == null || Binder.getCallingUid() != mRunningJob.getUid()) {
             if (DEBUG) {
                 Slog.d(TAG, "Stale callback received, ignoring.");
             }
@@ -261,12 +261,12 @@
     }
 
     /**
-     * Handles the lifecycle of the TaskService binding/callbacks, etc. The convention within this
+     * Handles the lifecycle of the JobService binding/callbacks, etc. The convention within this
      * class is to append 'H' to each function name that can only be called on this handler. This
      * isn't strictly necessary because all of these functions are private, but helps clarity.
      */
-    private class TaskServiceHandler extends Handler {
-        TaskServiceHandler(Looper looper) {
+    private class JobServiceHandler extends Handler {
+        JobServiceHandler(Looper looper) {
             super(looper);
         }
 
@@ -278,7 +278,7 @@
                     break;
                 case MSG_CALLBACK:
                     if (DEBUG) {
-                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningTask + " v:" +
+                        Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob + " v:" +
                                 VERB_STRINGS[mVerb]);
                     }
                     removeMessages(MSG_TIMEOUT);
@@ -292,7 +292,7 @@
                         handleFinishedH(reschedule);
                     } else {
                         if (DEBUG) {
-                            Slog.d(TAG, "Unrecognised callback: " + mRunningTask);
+                            Slog.d(TAG, "Unrecognised callback: " + mRunningJob);
                         }
                     }
                     break;
@@ -303,42 +303,42 @@
                     handleOpTimeoutH();
                     break;
                 case MSG_SHUTDOWN_EXECUTION:
-                    closeAndCleanupTaskH(true /* needsReschedule */);
+                    closeAndCleanupJobH(true /* needsReschedule */);
                     break;
                 default:
                     Log.e(TAG, "Unrecognised message: " + message);
             }
         }
 
-        /** Start the task on the service. */
+        /** Start the job on the service. */
         private void handleServiceBoundH() {
             if (mVerb != VERB_BINDING) {
-                Slog.e(TAG, "Sending onStartTask for a task that isn't pending. "
+                Slog.e(TAG, "Sending onStartJob for a job that isn't pending. "
                         + VERB_STRINGS[mVerb]);
-                closeAndCleanupTaskH(false /* reschedule */);
+                closeAndCleanupJobH(false /* reschedule */);
                 return;
             }
             if (mCancelled.get()) {
                 if (DEBUG) {
-                    Slog.d(TAG, "Task cancelled while waiting for bind to complete. "
-                            + mRunningTask);
+                    Slog.d(TAG, "Job cancelled while waiting for bind to complete. "
+                            + mRunningJob);
                 }
-                closeAndCleanupTaskH(true /* reschedule */);
+                closeAndCleanupJobH(true /* reschedule */);
                 return;
             }
             try {
                 mVerb = VERB_STARTING;
                 scheduleOpTimeOut();
-                service.startTask(mParams);
+                service.startJob(mParams);
             } catch (RemoteException e) {
                 Log.e(TAG, "Error sending onStart message to '" +
-                        mRunningTask.getServiceComponent().getShortClassName() + "' ", e);
+                        mRunningJob.getServiceComponent().getShortClassName() + "' ", e);
             }
         }
 
         /**
          * State behaviours.
-         * VERB_STARTING   -> Successful start, change task to VERB_EXECUTING and post timeout.
+         * VERB_STARTING   -> Successful start, change job to VERB_EXECUTING and post timeout.
          *     _PENDING    -> Error
          *     _EXECUTING  -> Error
          *     _STOPPING   -> Error
@@ -348,7 +348,7 @@
                 case VERB_STARTING:
                     mVerb = VERB_EXECUTING;
                     if (!workOngoing) {
-                        // Task is finished already so fast-forward to handleFinished.
+                        // Job is finished already so fast-forward to handleFinished.
                         handleFinishedH(false);
                         return;
                     }
@@ -360,14 +360,14 @@
                     scheduleOpTimeOut();
                     break;
                 default:
-                    Log.e(TAG, "Handling started task but task wasn't starting! Was "
+                    Log.e(TAG, "Handling started job but job wasn't starting! Was "
                             + VERB_STRINGS[mVerb] + ".");
                     return;
             }
         }
 
         /**
-         * VERB_EXECUTING  -> Client called taskFinished(), clean up and notify done.
+         * VERB_EXECUTING  -> Client called jobFinished(), clean up and notify done.
          *     _STOPPING   -> Successful finish, clean up and notify done.
          *     _STARTING   -> Error
          *     _PENDING    -> Error
@@ -376,20 +376,20 @@
             switch (mVerb) {
                 case VERB_EXECUTING:
                 case VERB_STOPPING:
-                    closeAndCleanupTaskH(reschedule);
+                    closeAndCleanupJobH(reschedule);
                     break;
                 default:
-                    Slog.e(TAG, "Got an execution complete message for a task that wasn't being" +
+                    Slog.e(TAG, "Got an execution complete message for a job that wasn't being" +
                             "executed. Was " + VERB_STRINGS[mVerb] + ".");
             }
         }
 
         /**
-         * A task can be in various states when a cancel request comes in:
+         * A job can be in various states when a cancel request comes in:
          * VERB_BINDING    -> Cancelled before bind completed. Mark as cancelled and wait for
          *                    {@link #onServiceConnected(android.content.ComponentName, android.os.IBinder)}
          *     _STARTING   -> Mark as cancelled and wait for
-         *                    {@link TaskServiceContext#acknowledgeStartMessage(int, boolean)}
+         *                    {@link JobServiceContext#acknowledgeStartMessage(int, boolean)}
          *     _EXECUTING  -> call {@link #sendStopMessageH}}.
          *     _ENDING     -> No point in doing anything here, so we ignore.
          */
@@ -406,48 +406,48 @@
                     // Nada.
                     break;
                 default:
-                    Slog.e(TAG, "Cancelling a task without a valid verb: " + mVerb);
+                    Slog.e(TAG, "Cancelling a job without a valid verb: " + mVerb);
                     break;
             }
         }
 
         /** Process MSG_TIMEOUT here. */
         private void handleOpTimeoutH() {
-            if (Log.isLoggable(TaskManagerService.TAG, Log.DEBUG)) {
+            if (Log.isLoggable(JobSchedulerService.TAG, Log.DEBUG)) {
                 Log.d(TAG, "MSG_TIMEOUT of " +
-                        mRunningTask.getServiceComponent().getShortClassName() + " : "
-                        + mParams.getTaskId());
+                        mRunningJob.getServiceComponent().getShortClassName() + " : "
+                        + mParams.getJobId());
             }
 
-            final int taskId = mParams.getTaskId();
+            final int jobId = mParams.getJobId();
             switch (mVerb) {
                 case VERB_STARTING:
                     // Client unresponsive - wedged or failed to respond in time. We don't really
-                    // know what happened so let's log it and notify the TaskManager
+                    // know what happened so let's log it and notify the JobScheduler
                     // FINISHED/NO-RETRY.
-                    Log.e(TAG, "No response from client for onStartTask '" +
-                            mRunningTask.getServiceComponent().getShortClassName() + "' tId: "
-                            + taskId);
-                    closeAndCleanupTaskH(false /* needsReschedule */);
+                    Log.e(TAG, "No response from client for onStartJob '" +
+                            mRunningJob.getServiceComponent().getShortClassName() + "' tId: "
+                            + jobId);
+                    closeAndCleanupJobH(false /* needsReschedule */);
                     break;
                 case VERB_STOPPING:
-                    // At least we got somewhere, so fail but ask the TaskManager to reschedule.
-                    Log.e(TAG, "No response from client for onStopTask, '" +
-                            mRunningTask.getServiceComponent().getShortClassName() + "' tId: "
-                            + taskId);
-                    closeAndCleanupTaskH(true /* needsReschedule */);
+                    // At least we got somewhere, so fail but ask the JobScheduler to reschedule.
+                    Log.e(TAG, "No response from client for onStopJob, '" +
+                            mRunningJob.getServiceComponent().getShortClassName() + "' tId: "
+                            + jobId);
+                    closeAndCleanupJobH(true /* needsReschedule */);
                     break;
                 case VERB_EXECUTING:
                     // Not an error - client ran out of time.
-                    Log.i(TAG, "Client timed out while executing (no taskFinished received)." +
+                    Log.i(TAG, "Client timed out while executing (no jobFinished received)." +
                             " sending onStop. "  +
-                            mRunningTask.getServiceComponent().getShortClassName() + "' tId: "
-                            + taskId);
+                            mRunningJob.getServiceComponent().getShortClassName() + "' tId: "
+                            + jobId);
                     sendStopMessageH();
                     break;
                 default:
-                    Log.e(TAG, "Handling timeout for an unknown active task state: "
-                            + mRunningTask);
+                    Log.e(TAG, "Handling timeout for an unknown active job state: "
+                            + mRunningJob);
                     return;
             }
         }
@@ -459,35 +459,34 @@
         private void sendStopMessageH() {
             mCallbackHandler.removeMessages(MSG_TIMEOUT);
             if (mVerb != VERB_EXECUTING) {
-                Log.e(TAG, "Sending onStopTask for a task that isn't started. " + mRunningTask);
-                closeAndCleanupTaskH(false /* reschedule */);
+                Log.e(TAG, "Sending onStopJob for a job that isn't started. " + mRunningJob);
+                closeAndCleanupJobH(false /* reschedule */);
                 return;
             }
             try {
                 mVerb = VERB_STOPPING;
                 scheduleOpTimeOut();
-                service.stopTask(mParams);
+                service.stopJob(mParams);
             } catch (RemoteException e) {
-                Log.e(TAG, "Error sending onStopTask to client.", e);
-                closeAndCleanupTaskH(false /* reschedule */);
+                Log.e(TAG, "Error sending onStopJob to client.", e);
+                closeAndCleanupJobH(false /* reschedule */);
             }
         }
 
         /**
-         * The provided task has finished, either by calling
-         * {@link android.app.task.TaskService#taskFinished(android.app.task.TaskParams, boolean)}
+         * The provided job has finished, either by calling
+         * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
          * or from acknowledging the stop message we sent. Either way, we're done tracking it and
          * we want to clean up internally.
          */
-        private void closeAndCleanupTaskH(boolean reschedule) {
+        private void closeAndCleanupJobH(boolean reschedule) {
             removeMessages(MSG_TIMEOUT);
+            mCompletedListener.onJobCompleted(mRunningJob, reschedule);
             synchronized (mLock) {
                 mWakeLock.release();
-                mContext.unbindService(TaskServiceContext.this);
-                mCompletedListener.onTaskCompleted(mRunningTask, reschedule);
-
+                mContext.unbindService(JobServiceContext.this);
                 mWakeLock = null;
-                mRunningTask = null;
+                mRunningJob = null;
                 mParams = null;
                 mVerb = -1;
                 mCancelled.set(false);
@@ -508,8 +507,8 @@
                     EXECUTING_TIMESLICE_MILLIS : OP_TIMEOUT_MILLIS;
             if (DEBUG) {
                 Slog.d(TAG, "Scheduling time out for '" +
-                        mRunningTask.getServiceComponent().getShortClassName() + "' tId: " +
-                        mParams.getTaskId() + ", in " + (timeoutMillis / 1000) + " s");
+                        mRunningJob.getServiceComponent().getShortClassName() + "' tId: " +
+                        mParams.getJobId() + ", in " + (timeoutMillis / 1000) + " s");
             }
             Message m = mCallbackHandler.obtainMessage(MSG_TIMEOUT);
             mCallbackHandler.sendMessageDelayed(m, timeoutMillis);
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
new file mode 100644
index 0000000..4ac26c1
--- /dev/null
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -0,0 +1,669 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job;
+
+import android.content.ComponentName;
+import android.app.job.JobInfo;
+import android.content.Context;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.PersistableBundle;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.AtomicFile;
+import android.util.ArraySet;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.IoThread;
+import com.android.server.job.controllers.JobStatus;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+/**
+ * Maintain a list of classes, and accessor methods/logic for these jobs.
+ * This class offers the following functionality:
+ *     - When a job is added, it will determine if the job requirements have changed (update) and
+ *       whether the controllers need to be updated.
+ *     - Persists JobInfos, figures out when to to rewrite the JobInfo to disk.
+ *     - Handles rescheduling of jobs.
+ *       - When a periodic job is executed and must be re-added.
+ *       - When a job fails and the client requests that it be retried with backoff.
+ *       - This class <strong>is not</strong> thread-safe.
+ *
+ * Note on locking:
+ *      All callers to this class must <strong>lock on the class object they are calling</strong>.
+ *      This is important b/c {@link com.android.server.job.JobStore.WriteJobsMapToDiskRunnable}
+ *      and {@link com.android.server.job.JobStore.ReadJobMapFromDiskRunnable} lock on that
+ *      object.
+ */
+public class JobStore {
+    private static final String TAG = "JobStore";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG;
+
+    /** Threshold to adjust how often we want to write to the db. */
+    private static final int MAX_OPS_BEFORE_WRITE = 1;
+    final ArraySet<JobStatus> mJobSet;
+    final Context mContext;
+
+    private int mDirtyOperations;
+
+    private static final Object sSingletonLock = new Object();
+    private final AtomicFile mJobsFile;
+    /** Handler backed by IoThread for writing to disk. */
+    private final Handler mIoHandler = IoThread.getHandler();
+    private static JobStore sSingleton;
+
+    /** Used by the {@link JobSchedulerService} to instantiate the JobStore. */
+    static JobStore initAndGet(JobSchedulerService jobManagerService) {
+        synchronized (sSingletonLock) {
+            if (sSingleton == null) {
+                sSingleton = new JobStore(jobManagerService.getContext(),
+                        Environment.getDataDirectory(), jobManagerService);
+            }
+            return sSingleton;
+        }
+    }
+
+    @VisibleForTesting
+    public static JobStore initAndGetForTesting(Context context, File dataDir,
+                                                 JobMapReadFinishedListener callback) {
+        return new JobStore(context, dataDir, callback);
+    }
+
+    private JobStore(Context context, File dataDir, JobMapReadFinishedListener callback) {
+        mContext = context;
+        mDirtyOperations = 0;
+
+        File systemDir = new File(dataDir, "system");
+        File jobDir = new File(systemDir, "job");
+        jobDir.mkdirs();
+        mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"));
+
+        mJobSet = new ArraySet<JobStatus>();
+
+        readJobMapFromDiskAsync(callback);
+    }
+
+    /**
+     * Add a job to the master list, persisting it if necessary. If the JobStatus already exists,
+     * it will be replaced.
+     * @param jobStatus Job to add.
+     * @return Whether or not an equivalent JobStatus was replaced by this operation.
+     */
+    public boolean add(JobStatus jobStatus) {
+        boolean replaced = mJobSet.remove(jobStatus);
+        mJobSet.add(jobStatus);
+        if (jobStatus.isPersisted()) {
+            maybeWriteStatusToDiskAsync();
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "Added job status to store: " + jobStatus);
+        }
+        return replaced;
+    }
+
+    /**
+     * Whether this jobStatus object already exists in the JobStore.
+     */
+    public boolean containsJobIdForUid(int jobId, int uId) {
+        for (JobStatus ts : mJobSet) {
+            if (ts.getUid() == uId && ts.getJobId() == jobId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public int size() {
+        return mJobSet.size();
+    }
+
+    /**
+     * Remove the provided job. Will also delete the job if it was persisted.
+     * @return Whether or not the job existed to be removed.
+     */
+    public boolean remove(JobStatus jobStatus) {
+        boolean removed = mJobSet.remove(jobStatus);
+        if (!removed) {
+            if (DEBUG) {
+                Slog.d(TAG, "Couldn't remove job: didn't exist: " + jobStatus);
+            }
+            return false;
+        }
+        maybeWriteStatusToDiskAsync();
+        return removed;
+    }
+
+    @VisibleForTesting
+    public void clear() {
+        mJobSet.clear();
+        maybeWriteStatusToDiskAsync();
+    }
+
+    public List<JobStatus> getJobsByUser(int userHandle) {
+        List<JobStatus> matchingJobs = new ArrayList<JobStatus>();
+        Iterator<JobStatus> it = mJobSet.iterator();
+        while (it.hasNext()) {
+            JobStatus ts = it.next();
+            if (UserHandle.getUserId(ts.getUid()) == userHandle) {
+                matchingJobs.add(ts);
+            }
+        }
+        return matchingJobs;
+    }
+
+    /**
+     * @param uid Uid of the requesting app.
+     * @return All JobStatus objects for a given uid from the master list.
+     */
+    public List<JobStatus> getJobsByUid(int uid) {
+        List<JobStatus> matchingJobs = new ArrayList<JobStatus>();
+        Iterator<JobStatus> it = mJobSet.iterator();
+        while (it.hasNext()) {
+            JobStatus ts = it.next();
+            if (ts.getUid() == uid) {
+                matchingJobs.add(ts);
+            }
+        }
+        return matchingJobs;
+    }
+
+    /**
+     * @param uid Uid of the requesting app.
+     * @param jobId Job id, specified at schedule-time.
+     * @return the JobStatus that matches the provided uId and jobId, or null if none found.
+     */
+    public JobStatus getJobByUidAndJobId(int uid, int jobId) {
+        Iterator<JobStatus> it = mJobSet.iterator();
+        while (it.hasNext()) {
+            JobStatus ts = it.next();
+            if (ts.getUid() == uid && ts.getJobId() == jobId) {
+                return ts;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @return The live array of JobStatus objects.
+     */
+    public ArraySet<JobStatus> getJobs() {
+        return mJobSet;
+    }
+
+    /** Version of the db schema. */
+    private static final int JOBS_FILE_VERSION = 0;
+    /** Tag corresponds to constraints this job needs. */
+    private static final String XML_TAG_PARAMS_CONSTRAINTS = "constraints";
+    /** Tag corresponds to execution parameters. */
+    private static final String XML_TAG_PERIODIC = "periodic";
+    private static final String XML_TAG_ONEOFF = "one-off";
+    private static final String XML_TAG_EXTRAS = "extras";
+
+    /**
+     * Every time the state changes we write all the jobs in one swath, instead of trying to
+     * track incremental changes.
+     * @return Whether the operation was successful. This will only fail for e.g. if the system is
+     * low on storage. If this happens, we continue as normal
+     */
+    private void maybeWriteStatusToDiskAsync() {
+        mDirtyOperations++;
+        if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) {
+            if (DEBUG) {
+                Slog.v(TAG, "Writing jobs to disk.");
+            }
+            mIoHandler.post(new WriteJobsMapToDiskRunnable());
+        }
+    }
+
+    private void readJobMapFromDiskAsync(JobMapReadFinishedListener callback) {
+        mIoHandler.post(new ReadJobMapFromDiskRunnable(callback));
+    }
+
+    public void readJobMapFromDisk(JobMapReadFinishedListener callback) {
+        new ReadJobMapFromDiskRunnable(callback).run();
+    }
+
+    /**
+     * Runnable that writes {@link #mJobSet} out to xml.
+     * NOTE: This Runnable locks on JobStore.this
+     */
+    private class WriteJobsMapToDiskRunnable implements Runnable {
+        @Override
+        public void run() {
+            final long startElapsed = SystemClock.elapsedRealtime();
+            List<JobStatus> mStoreCopy = new ArrayList<JobStatus>();
+            synchronized (JobStore.this) {
+                // Copy over the jobs so we can release the lock before writing.
+                for (JobStatus jobStatus : mJobSet) {
+                    JobStatus copy = new JobStatus(jobStatus.getJob(), jobStatus.getUid(),
+                            jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed());
+                    mStoreCopy.add(copy);
+                }
+            }
+            writeJobsMapImpl(mStoreCopy);
+            if (JobSchedulerService.DEBUG) {
+                Slog.v(TAG, "Finished writing, took " + (SystemClock.elapsedRealtime()
+                        - startElapsed) + "ms");
+            }
+        }
+
+        private void writeJobsMapImpl(List<JobStatus> jobList) {
+            try {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                XmlSerializer out = new FastXmlSerializer();
+                out.setOutput(baos, "utf-8");
+                out.startDocument(null, true);
+                out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+                out.startTag(null, "job-info");
+                out.attribute(null, "version", Integer.toString(JOBS_FILE_VERSION));
+                for (JobStatus jobStatus : jobList) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Saving job " + jobStatus.getJobId());
+                    }
+                    out.startTag(null, "job");
+                    addIdentifierAttributesToJobTag(out, jobStatus);
+                    writeConstraintsToXml(out, jobStatus);
+                    writeExecutionCriteriaToXml(out, jobStatus);
+                    writeBundleToXml(jobStatus.getExtras(), out);
+                    out.endTag(null, "job");
+                }
+                out.endTag(null, "job-info");
+                out.endDocument();
+
+                // Write out to disk in one fell sweep.
+                FileOutputStream fos = mJobsFile.startWrite();
+                fos.write(baos.toByteArray());
+                mJobsFile.finishWrite(fos);
+                mDirtyOperations = 0;
+            } catch (IOException e) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Error writing out job data.", e);
+                }
+            } catch (XmlPullParserException e) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error persisting bundle.", e);
+                }
+            }
+        }
+
+        /** Write out a tag with data comprising the required fields of this job and its client. */
+        private void addIdentifierAttributesToJobTag(XmlSerializer out, JobStatus jobStatus)
+                throws IOException {
+            out.attribute(null, "jobid", Integer.toString(jobStatus.getJobId()));
+            out.attribute(null, "package", jobStatus.getServiceComponent().getPackageName());
+            out.attribute(null, "class", jobStatus.getServiceComponent().getClassName());
+            out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
+        }
+
+        private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
+                throws IOException, XmlPullParserException {
+            out.startTag(null, XML_TAG_EXTRAS);
+            extras.saveToXml(out);
+            out.endTag(null, XML_TAG_EXTRAS);
+        }
+        /**
+         * Write out a tag with data identifying this job's constraints. If the constraint isn't here
+         * it doesn't apply.
+         */
+        private void writeConstraintsToXml(XmlSerializer out, JobStatus jobStatus) throws IOException {
+            out.startTag(null, XML_TAG_PARAMS_CONSTRAINTS);
+            if (jobStatus.hasUnmeteredConstraint()) {
+                out.attribute(null, "unmetered", Boolean.toString(true));
+            }
+            if (jobStatus.hasConnectivityConstraint()) {
+                out.attribute(null, "connectivity", Boolean.toString(true));
+            }
+            if (jobStatus.hasIdleConstraint()) {
+                out.attribute(null, "idle", Boolean.toString(true));
+            }
+            if (jobStatus.hasChargingConstraint()) {
+                out.attribute(null, "charging", Boolean.toString(true));
+            }
+            out.endTag(null, XML_TAG_PARAMS_CONSTRAINTS);
+        }
+
+        private void writeExecutionCriteriaToXml(XmlSerializer out, JobStatus jobStatus)
+                throws IOException {
+            final JobInfo job = jobStatus.getJob();
+            if (jobStatus.getJob().isPeriodic()) {
+                out.startTag(null, XML_TAG_PERIODIC);
+                out.attribute(null, "period", Long.toString(job.getIntervalMillis()));
+            } else {
+                out.startTag(null, XML_TAG_ONEOFF);
+            }
+
+            if (jobStatus.hasDeadlineConstraint()) {
+                // Wall clock deadline.
+                final long deadlineWallclock =  System.currentTimeMillis() +
+                        (jobStatus.getLatestRunTimeElapsed() - SystemClock.elapsedRealtime());
+                out.attribute(null, "deadline", Long.toString(deadlineWallclock));
+            }
+            if (jobStatus.hasTimingDelayConstraint()) {
+                final long delayWallclock = System.currentTimeMillis() +
+                        (jobStatus.getEarliestRunTime() - SystemClock.elapsedRealtime());
+                out.attribute(null, "delay", Long.toString(delayWallclock));
+            }
+
+            // Only write out back-off policy if it differs from the default.
+            // This also helps the case where the job is idle -> these aren't allowed to specify
+            // back-off.
+            if (jobStatus.getJob().getInitialBackoffMillis() != JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS
+                    || jobStatus.getJob().getBackoffPolicy() != JobInfo.DEFAULT_BACKOFF_POLICY) {
+                out.attribute(null, "backoff-policy", Integer.toString(job.getBackoffPolicy()));
+                out.attribute(null, "initial-backoff", Long.toString(job.getInitialBackoffMillis()));
+            }
+            if (job.isPeriodic()) {
+                out.endTag(null, XML_TAG_PERIODIC);
+            } else {
+                out.endTag(null, XML_TAG_ONEOFF);
+            }
+        }
+    }
+
+    /**
+     * Runnable that reads list of persisted job from xml.
+     * NOTE: This Runnable locks on JobStore.this
+     */
+    private class ReadJobMapFromDiskRunnable implements Runnable {
+        private JobMapReadFinishedListener mCallback;
+        public ReadJobMapFromDiskRunnable(JobMapReadFinishedListener callback) {
+            mCallback = callback;
+        }
+
+        @Override
+        public void run() {
+            try {
+                List<JobStatus> jobs;
+                FileInputStream fis = mJobsFile.openRead();
+                synchronized (JobStore.this) {
+                    jobs = readJobMapImpl(fis);
+                }
+                fis.close();
+                if (jobs != null) {
+                    mCallback.onJobMapReadFinished(jobs);
+                }
+            } catch (FileNotFoundException e) {
+                if (JobSchedulerService.DEBUG) {
+                    Slog.d(TAG, "Could not find jobs file, probably there was nothing to load.");
+                }
+            } catch (XmlPullParserException e) {
+                if (JobSchedulerService.DEBUG) {
+                    Slog.d(TAG, "Error parsing xml.", e);
+                }
+            } catch (IOException e) {
+                if (JobSchedulerService.DEBUG) {
+                    Slog.d(TAG, "Error parsing xml.", e);
+                }
+            }
+        }
+
+        private List<JobStatus> readJobMapImpl(FileInputStream fis) throws XmlPullParserException, IOException {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, null);
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.START_TAG &&
+                    eventType != XmlPullParser.END_DOCUMENT) {
+                eventType = parser.next();
+                Slog.d(TAG, parser.getName());
+            }
+            if (eventType == XmlPullParser.END_DOCUMENT) {
+                if (DEBUG) {
+                    Slog.d(TAG, "No persisted jobs.");
+                }
+                return null;
+            }
+
+            String tagName = parser.getName();
+            if ("job-info".equals(tagName)) {
+                final List<JobStatus> jobs = new ArrayList<JobStatus>();
+                // Read in version info.
+                try {
+                    int version = Integer.valueOf(parser.getAttributeValue(null, "version"));
+                    if (version != JOBS_FILE_VERSION) {
+                        Slog.d(TAG, "Invalid version number, aborting jobs file read.");
+                        return null;
+                    }
+                } catch (NumberFormatException e) {
+                    Slog.e(TAG, "Invalid version number, aborting jobs file read.");
+                    return null;
+                }
+                eventType = parser.next();
+                do {
+                    // Read each <job/>
+                    if (eventType == XmlPullParser.START_TAG) {
+                        tagName = parser.getName();
+                        // Start reading job.
+                        if ("job".equals(tagName)) {
+                            JobStatus persistedJob = restoreJobFromXml(parser);
+                            if (persistedJob != null) {
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Read out " + persistedJob);
+                                }
+                                jobs.add(persistedJob);
+                            } else {
+                                Slog.d(TAG, "Error reading job from file.");
+                            }
+                        }
+                    }
+                    eventType = parser.next();
+                } while (eventType != XmlPullParser.END_DOCUMENT);
+                return jobs;
+            }
+            return null;
+        }
+
+        /**
+         * @param parser Xml parser at the beginning of a "<job/>" tag. The next "parser.next()" call
+         *               will take the parser into the body of the job tag.
+         * @return Newly instantiated job holding all the information we just read out of the xml tag.
+         */
+        private JobStatus restoreJobFromXml(XmlPullParser parser) throws XmlPullParserException,
+                IOException {
+            JobInfo.Builder jobBuilder;
+            int uid;
+
+            // Read out job identifier attributes.
+            try {
+                jobBuilder = buildBuilderFromXml(parser);
+                uid = Integer.valueOf(parser.getAttributeValue(null, "uid"));
+            } catch (NumberFormatException e) {
+                Slog.e(TAG, "Error parsing job's required fields, skipping");
+                return null;
+            }
+
+            int eventType;
+            // Read out constraints tag.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);  // Push through to next START_TAG.
+
+            if (!(eventType == XmlPullParser.START_TAG &&
+                    XML_TAG_PARAMS_CONSTRAINTS.equals(parser.getName()))) {
+                // Expecting a <constraints> start tag.
+                return null;
+            }
+            try {
+                buildConstraintsFromXml(jobBuilder, parser);
+            } catch (NumberFormatException e) {
+                Slog.d(TAG, "Error reading constraints, skipping.");
+                return null;
+            }
+            parser.next(); // Consume </constraints>
+
+            // Read out execution parameters tag.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);
+            if (eventType != XmlPullParser.START_TAG) {
+                return null;
+            }
+
+            Pair<Long, Long> runtimes;
+            try {
+                runtimes = buildExecutionTimesFromXml(parser);
+            } catch (NumberFormatException e) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error parsing execution time parameters, skipping.");
+                }
+                return null;
+            }
+
+            if (XML_TAG_PERIODIC.equals(parser.getName())) {
+                try {
+                    String val = parser.getAttributeValue(null, "period");
+                    jobBuilder.setPeriodic(Long.valueOf(val));
+                } catch (NumberFormatException e) {
+                    Slog.d(TAG, "Error reading periodic execution criteria, skipping.");
+                    return null;
+                }
+            } else if (XML_TAG_ONEOFF.equals(parser.getName())) {
+                try {
+                    if (runtimes.first != JobStatus.NO_EARLIEST_RUNTIME) {
+                        jobBuilder.setMinimumLatency(runtimes.first - SystemClock.elapsedRealtime());
+                    }
+                    if (runtimes.second != JobStatus.NO_LATEST_RUNTIME) {
+                        jobBuilder.setOverrideDeadline(
+                                runtimes.second - SystemClock.elapsedRealtime());
+                    }
+                } catch (NumberFormatException e) {
+                    Slog.d(TAG, "Error reading job execution criteria, skipping.");
+                    return null;
+                }
+            } else {
+                if (DEBUG) {
+                    Slog.d(TAG, "Invalid parameter tag, skipping - " + parser.getName());
+                }
+                // Expecting a parameters start tag.
+                return null;
+            }
+            maybeBuildBackoffPolicyFromXml(jobBuilder, parser);
+
+            parser.nextTag(); // Consume parameters end tag.
+
+            // Read out extras Bundle.
+            do {
+                eventType = parser.next();
+            } while (eventType == XmlPullParser.TEXT);
+            if (!(eventType == XmlPullParser.START_TAG && XML_TAG_EXTRAS.equals(parser.getName()))) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Error reading extras, skipping.");
+                }
+                return null;
+            }
+
+            PersistableBundle extras = PersistableBundle.restoreFromXml(parser);
+            jobBuilder.setExtras(extras);
+            parser.nextTag(); // Consume </extras>
+
+            return new JobStatus(jobBuilder.build(), uid, runtimes.first, runtimes.second);
+        }
+
+        private JobInfo.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
+            // Pull out required fields from <job> attributes.
+            int jobId = Integer.valueOf(parser.getAttributeValue(null, "jobid"));
+            String packageName = parser.getAttributeValue(null, "package");
+            String className = parser.getAttributeValue(null, "class");
+            ComponentName cname = new ComponentName(packageName, className);
+
+            return new JobInfo.Builder(jobId, cname);
+        }
+
+        private void buildConstraintsFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser) {
+            String val = parser.getAttributeValue(null, "unmetered");
+            if (val != null) {
+                jobBuilder.setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED);
+            }
+            val = parser.getAttributeValue(null, "connectivity");
+            if (val != null) {
+                jobBuilder.setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY);
+            }
+            val = parser.getAttributeValue(null, "idle");
+            if (val != null) {
+                jobBuilder.setRequiresDeviceIdle(true);
+            }
+            val = parser.getAttributeValue(null, "charging");
+            if (val != null) {
+                jobBuilder.setRequiresCharging(true);
+            }
+        }
+
+        /**
+         * Builds the back-off policy out of the params tag. These attributes may not exist, depending
+         * on whether the back-off was set when the job was first scheduled.
+         */
+        private void maybeBuildBackoffPolicyFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser) {
+            String val = parser.getAttributeValue(null, "initial-backoff");
+            if (val != null) {
+                long initialBackoff = Long.valueOf(val);
+                val = parser.getAttributeValue(null, "backoff-policy");
+                int backoffPolicy = Integer.valueOf(val);  // Will throw NFE which we catch higher up.
+                jobBuilder.setBackoffCriteria(initialBackoff, backoffPolicy);
+            }
+        }
+
+        /**
+         * Convenience function to read out and convert deadline and delay from xml into elapsed real
+         * time.
+         * @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime
+         * and the second is the latest elapsed runtime.
+         */
+        private Pair<Long, Long> buildExecutionTimesFromXml(XmlPullParser parser)
+                throws NumberFormatException {
+            // Pull out execution time data.
+            final long nowWallclock = System.currentTimeMillis();
+            final long nowElapsed = SystemClock.elapsedRealtime();
+
+            long earliestRunTimeElapsed = JobStatus.NO_EARLIEST_RUNTIME;
+            long latestRunTimeElapsed = JobStatus.NO_LATEST_RUNTIME;
+            String val = parser.getAttributeValue(null, "deadline");
+            if (val != null) {
+                long latestRuntimeWallclock = Long.valueOf(val);
+                long maxDelayElapsed =
+                        Math.max(latestRuntimeWallclock - nowWallclock, 0);
+                latestRunTimeElapsed = nowElapsed + maxDelayElapsed;
+            }
+            val = parser.getAttributeValue(null, "delay");
+            if (val != null) {
+                long earliestRuntimeWallclock = Long.valueOf(val);
+                long minDelayElapsed =
+                        Math.max(earliestRuntimeWallclock - nowWallclock, 0);
+                earliestRunTimeElapsed = nowElapsed + minDelayElapsed;
+
+            }
+            return Pair.create(earliestRunTimeElapsed, latestRunTimeElapsed);
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/job/StateChangedListener.java b/services/core/java/com/android/server/job/StateChangedListener.java
new file mode 100644
index 0000000..90c203a
--- /dev/null
+++ b/services/core/java/com/android/server/job/StateChangedListener.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.server.job;
+
+import com.android.server.job.controllers.JobStatus;
+
+/**
+ * Interface through which a {@link com.android.server.job.controllers.StateController} informs
+ * the {@link com.android.server.job.JobSchedulerService} that there are some tasks potentially
+ * ready to be run.
+ */
+public interface StateChangedListener {
+    /**
+     * Called by the controller to notify the JobManager that it should check on the state of a
+     * task.
+     */
+    public void onControllerStateChanged();
+
+    /**
+     * Called by the controller to notify the JobManager that regardless of the state of the task,
+     * it must be run immediately.
+     * @param jobStatus The state of the task which is to be run immediately.
+     */
+    public void onRunJobNow(JobStatus jobStatus);
+}
diff --git a/services/core/java/com/android/server/task/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
similarity index 80%
rename from services/core/java/com/android/server/task/controllers/BatteryController.java
rename to services/core/java/com/android/server/job/controllers/BatteryController.java
index 443527f..4aef2d31 100644
--- a/services/core/java/com/android/server/task/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -32,11 +32,12 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.BatteryService;
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -45,7 +46,7 @@
  * ACTION_BATTERY_OK.
  */
 public class BatteryController extends StateController {
-    private static final String TAG = "BatteryController";
+    private static final String TAG = "JobScheduler.Batt";
 
     private static final Object sCreationLock = new Object();
     private static volatile BatteryController sController;
@@ -54,10 +55,10 @@
     /** Wait this long after phone is plugged in before doing any work. */
     private static final long STABLE_CHARGING_THRESHOLD_MILLIS = 2 * 60 * 1000; // 2 minutes.
 
-    private List<TaskStatus> mTrackedTasks = new ArrayList<TaskStatus>();
+    private List<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
     private ChargingTracker mChargeTracker;
 
-    public static BatteryController get(TaskManagerService taskManagerService) {
+    public static BatteryController get(JobSchedulerService taskManagerService) {
         synchronized (sCreationLock) {
             if (sController == null) {
                 sController = new BatteryController(taskManagerService,
@@ -85,18 +86,21 @@
     }
 
     @Override
-    public void maybeStartTrackingTask(TaskStatus taskStatus) {
+    public void maybeStartTrackingJob(JobStatus taskStatus) {
         if (taskStatus.hasChargingConstraint()) {
+            final boolean isOnStablePower = mChargeTracker.isOnStablePower();
             synchronized (mTrackedTasks) {
                 mTrackedTasks.add(taskStatus);
-                taskStatus.chargingConstraintSatisfied.set(mChargeTracker.isOnStablePower());
+                taskStatus.chargingConstraintSatisfied.set(isOnStablePower);
+            }
+            if (isOnStablePower) {
+                mStateChangedListener.onControllerStateChanged();
             }
         }
-
     }
 
     @Override
-    public void maybeStopTrackingTask(TaskStatus taskStatus) {
+    public void maybeStopTrackingJob(JobStatus taskStatus) {
         if (taskStatus.hasChargingConstraint()) {
             synchronized (mTrackedTasks) {
                 mTrackedTasks.remove(taskStatus);
@@ -106,9 +110,12 @@
 
     private void maybeReportNewChargingState() {
         final boolean stablePower = mChargeTracker.isOnStablePower();
+        if (DEBUG) {
+            Slog.d(TAG, "maybeReportNewChargingState: " + stablePower);
+        }
         boolean reportChange = false;
         synchronized (mTrackedTasks) {
-            for (TaskStatus ts : mTrackedTasks) {
+            for (JobStatus ts : mTrackedTasks) {
                 boolean previous = ts.chargingConstraintSatisfied.getAndSet(stablePower);
                 if (previous != stablePower) {
                     reportChange = true;
@@ -133,8 +140,7 @@
 
         public ChargingTracker() {
             mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-            Intent intent = new Intent(ACTION_CHARGING_STABLE)
-                    .setComponent(new ComponentName(mContext, this.getClass()));
+            Intent intent = new Intent(ACTION_CHARGING_STABLE);
             mStableChargingTriggerIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
         }
 
@@ -147,6 +153,8 @@
             // Charging/not charging.
             filter.addAction(Intent.ACTION_POWER_CONNECTED);
             filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
+            // Charging stable.
+            filter.addAction(ACTION_CHARGING_STABLE);
             mContext.registerReceiver(this, filter);
 
             // Initialise tracker state.
@@ -189,6 +197,10 @@
                 mBatteryHealthy = true;
                 maybeReportNewChargingState();
             } else if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Received charging intent, setting alarm for "
+                            + STABLE_CHARGING_THRESHOLD_MILLIS);
+                }
                 // Set up an alarm for ACTION_CHARGING_STABLE - we don't want to kick off tasks
                 // here if the user unplugs the phone immediately.
                 mAlarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
@@ -196,6 +208,9 @@
                         mStableChargingTriggerIntent);
                 mCharging = true;
             } else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Disconnected from power, cancelling any set alarms.");
+                }
                 // If an alarm is set, breathe a sigh of relief and cancel it - crisis averted.
                 mAlarm.cancel(mStableChargingTriggerIntent);
                 mCharging = false;
@@ -203,7 +218,8 @@
             }else if (ACTION_CHARGING_STABLE.equals(action)) {
                 // Here's where we actually do the notify for a task being ready.
                 if (DEBUG) {
-                    Slog.d(TAG, "Battery connected fired @ " + SystemClock.elapsedRealtime());
+                    Slog.d(TAG, "Battery connected fired @ " + SystemClock.elapsedRealtime()
+                            + " charging: " + mCharging);
                 }
                 if (mCharging) {  // Should never receive this intent if mCharging is false.
                     maybeReportNewChargingState();
@@ -214,6 +230,17 @@
 
     @Override
     public void dumpControllerState(PrintWriter pw) {
-
+        pw.println("Batt.");
+        pw.println("Stable power: " + mChargeTracker.isOnStablePower());
+        synchronized (mTrackedTasks) {
+            Iterator<JobStatus> it = mTrackedTasks.iterator();
+            if (it.hasNext()) {
+                pw.print(String.valueOf(it.next().hashCode()));
+            }
+            while (it.hasNext()) {
+                pw.print("," + String.valueOf(it.next().hashCode()));
+            }
+            pw.println();
+        }
     }
 }
diff --git a/services/core/java/com/android/server/task/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
similarity index 75%
rename from services/core/java/com/android/server/task/controllers/ConnectivityController.java
rename to services/core/java/com/android/server/job/controllers/ConnectivityController.java
index c1ab0f0..daba0d9 100644
--- a/services/core/java/com/android/server/task/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 
 import android.content.BroadcastReceiver;
@@ -28,8 +28,8 @@
 import android.util.Slog;
 
 import com.android.server.ConnectivityService;
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 import java.util.LinkedList;
@@ -42,9 +42,9 @@
  */
 public class ConnectivityController extends StateController implements
         ConnectivityManager.OnNetworkActiveListener {
-    private static final String TAG = "TaskManager.Conn";
+    private static final String TAG = "JobScheduler.Conn";
 
-    private final List<TaskStatus> mTrackedTasks = new LinkedList<TaskStatus>();
+    private final List<JobStatus> mTrackedJobs = new LinkedList<JobStatus>();
     private final BroadcastReceiver mConnectivityChangedReceiver =
             new ConnectivityChangedReceiver();
     /** Singleton. */
@@ -55,10 +55,10 @@
     /** Track whether the latest active network is connected. */
     private boolean mNetworkConnected;
 
-    public static ConnectivityController get(TaskManagerService taskManager) {
+    public static ConnectivityController get(JobSchedulerService jms) {
         synchronized (sCreationLock) {
             if (mSingleton == null) {
-                mSingleton = new ConnectivityController(taskManager, taskManager.getContext());
+                mSingleton = new ConnectivityController(jms, jms.getContext());
             }
             return mSingleton;
         }
@@ -82,21 +82,21 @@
     }
 
     @Override
-    public void maybeStartTrackingTask(TaskStatus taskStatus) {
-        if (taskStatus.hasConnectivityConstraint() || taskStatus.hasUnmeteredConstraint()) {
-            synchronized (mTrackedTasks) {
-                taskStatus.connectivityConstraintSatisfied.set(mNetworkConnected);
-                taskStatus.unmeteredConstraintSatisfied.set(mNetworkUnmetered);
-                mTrackedTasks.add(taskStatus);
+    public void maybeStartTrackingJob(JobStatus jobStatus) {
+        if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
+            synchronized (mTrackedJobs) {
+                jobStatus.connectivityConstraintSatisfied.set(mNetworkConnected);
+                jobStatus.unmeteredConstraintSatisfied.set(mNetworkUnmetered);
+                mTrackedJobs.add(jobStatus);
             }
         }
     }
 
     @Override
-    public void maybeStopTrackingTask(TaskStatus taskStatus) {
-        if (taskStatus.hasConnectivityConstraint() || taskStatus.hasUnmeteredConstraint()) {
-            synchronized (mTrackedTasks) {
-                mTrackedTasks.remove(taskStatus);
+    public void maybeStopTrackingJob(JobStatus jobStatus) {
+        if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) {
+            synchronized (mTrackedJobs) {
+                mTrackedJobs.remove(jobStatus);
             }
         }
     }
@@ -104,16 +104,16 @@
     /**
      * @param userId Id of the user for whom we are updating the connectivity state.
      */
-    private void updateTrackedTasks(int userId) {
-        synchronized (mTrackedTasks) {
+    private void updateTrackedJobs(int userId) {
+        synchronized (mTrackedJobs) {
             boolean changed = false;
-            for (TaskStatus ts : mTrackedTasks) {
-                if (ts.getUserId() != userId) {
+            for (JobStatus js : mTrackedJobs) {
+                if (js.getUserId() != userId) {
                     continue;
                 }
                 boolean prevIsConnected =
-                        ts.connectivityConstraintSatisfied.getAndSet(mNetworkConnected);
-                boolean prevIsMetered = ts.unmeteredConstraintSatisfied.getAndSet(mNetworkUnmetered);
+                        js.connectivityConstraintSatisfied.getAndSet(mNetworkConnected);
+                boolean prevIsMetered = js.unmeteredConstraintSatisfied.getAndSet(mNetworkUnmetered);
                 if (prevIsConnected != mNetworkConnected || prevIsMetered != mNetworkUnmetered) {
                     changed = true;
                 }
@@ -125,16 +125,16 @@
     }
 
     /**
-     * We know the network has just come up. We want to run any tasks that are ready.
+     * We know the network has just come up. We want to run any jobs that are ready.
      */
     public synchronized void onNetworkActive() {
-        synchronized (mTrackedTasks) {
-            for (TaskStatus ts : mTrackedTasks) {
-                if (ts.isReady()) {
+        synchronized (mTrackedJobs) {
+            for (JobStatus js : mTrackedJobs) {
+                if (js.isReady()) {
                     if (DEBUG) {
-                        Slog.d(TAG, "Running " + ts + " due to network activity.");
+                        Slog.d(TAG, "Running " + js + " due to network activity.");
                     }
-                    mStateChangedListener.onRunTaskNow(ts);
+                    mStateChangedListener.onRunJobNow(js);
                 }
             }
         }
@@ -169,7 +169,7 @@
                 if (activeNetwork == null) {
                     mNetworkUnmetered = false;
                     mNetworkConnected = false;
-                    updateTrackedTasks(userid);
+                    updateTrackedJobs(userid);
                 } else if (activeNetwork.getType() == networkType) {
                     mNetworkUnmetered = false;
                     mNetworkConnected = !intent.getBooleanExtra(
@@ -177,7 +177,7 @@
                     if (mNetworkConnected) {  // No point making the call if we know there's no conn.
                         mNetworkUnmetered = !connManager.isActiveNetworkMetered();
                     }
-                    updateTrackedTasks(userid);
+                    updateTrackedJobs(userid);
                 }
             } else {
                 if (DEBUG) {
@@ -191,10 +191,10 @@
     public void dumpControllerState(PrintWriter pw) {
         pw.println("Conn.");
         pw.println("connected: " + mNetworkConnected + " unmetered: " + mNetworkUnmetered);
-        for (TaskStatus ts: mTrackedTasks) {
-            pw.println(String.valueOf(ts.hashCode()).substring(0, 3) + ".."
-                    + ": C=" + ts.hasConnectivityConstraint()
-                    + ", UM=" + ts.hasUnmeteredConstraint());
+        for (JobStatus js: mTrackedJobs) {
+            pw.println(String.valueOf(js.hashCode()).substring(0, 3) + ".."
+                    + ": C=" + js.hasConnectivityConstraint()
+                    + ", UM=" + js.hasUnmeteredConstraint());
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/task/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
similarity index 92%
rename from services/core/java/com/android/server/task/controllers/IdleController.java
rename to services/core/java/com/android/server/job/controllers/IdleController.java
index e749b00..07ffe4d 100644
--- a/services/core/java/com/android/server/task/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -29,8 +29,8 @@
 import android.os.SystemClock;
 import android.util.Slog;
 
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 public class IdleController extends StateController {
     private static final String TAG = "IdleController";
@@ -43,14 +43,14 @@
     private static final String ACTION_TRIGGER_IDLE =
             "com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE";
 
-    final ArrayList<TaskStatus> mTrackedTasks = new ArrayList<TaskStatus>();
+    final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
     IdlenessTracker mIdleTracker;
 
     // Singleton factory
     private static Object sCreationLock = new Object();
     private static volatile IdleController sController;
 
-    public static IdleController get(TaskManagerService service) {
+    public static IdleController get(JobSchedulerService service) {
         synchronized (sCreationLock) {
             if (sController == null) {
                 sController = new IdleController(service, service.getContext());
@@ -68,7 +68,7 @@
      * StateController interface
      */
     @Override
-    public void maybeStartTrackingTask(TaskStatus taskStatus) {
+    public void maybeStartTrackingJob(JobStatus taskStatus) {
         if (taskStatus.hasIdleConstraint()) {
             synchronized (mTrackedTasks) {
                 mTrackedTasks.add(taskStatus);
@@ -78,7 +78,7 @@
     }
 
     @Override
-    public void maybeStopTrackingTask(TaskStatus taskStatus) {
+    public void maybeStopTrackingJob(JobStatus taskStatus) {
         synchronized (mTrackedTasks) {
             mTrackedTasks.remove(taskStatus);
         }
@@ -89,7 +89,7 @@
      */
     void reportNewIdleState(boolean isIdle) {
         synchronized (mTrackedTasks) {
-            for (TaskStatus task : mTrackedTasks) {
+            for (JobStatus task : mTrackedTasks) {
                 task.idleConstraintSatisfied.set(isIdle);
             }
         }
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
new file mode 100644
index 0000000..15a6b25
--- /dev/null
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job.controllers;
+
+import android.app.job.JobInfo;
+import android.content.ComponentName;
+import android.os.PersistableBundle;
+import android.os.SystemClock;
+import android.os.UserHandle;
+
+import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Uniquely identifies a job internally.
+ * Created from the public {@link android.app.job.JobInfo} object when it lands on the scheduler.
+ * Contains current state of the requirements of the job, as well as a function to evaluate
+ * whether it's ready to run.
+ * This object is shared among the various controllers - hence why the different fields are atomic.
+ * This isn't strictly necessary because each controller is only interested in a specific field,
+ * and the receivers that are listening for global state change will all run on the main looper,
+ * but we don't enforce that so this is safer.
+ * @hide
+ */
+public class JobStatus {
+    public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
+    public static final long NO_EARLIEST_RUNTIME = 0L;
+
+    final JobInfo job;
+    final int uId;
+
+    /** At reschedule time we need to know whether to update job on disk. */
+    final boolean persisted;
+
+    // Constraints.
+    final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean deadlineConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean idleConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean unmeteredConstraintSatisfied = new AtomicBoolean();
+    final AtomicBoolean connectivityConstraintSatisfied = new AtomicBoolean();
+
+    /**
+     * Earliest point in the future at which this job will be eligible to run. A value of 0
+     * indicates there is no delay constraint. See {@link #hasTimingDelayConstraint()}.
+     */
+    private long earliestRunTimeElapsedMillis;
+    /**
+     * Latest point in the future at which this job must be run. A value of {@link Long#MAX_VALUE}
+     * indicates there is no deadline constraint. See {@link #hasDeadlineConstraint()}.
+     */
+    private long latestRunTimeElapsedMillis;
+    /** How many times this job has failed, used to compute back-off. */
+    private final int numFailures;
+
+    /** Provide a handle to the service that this job will be run on. */
+    public int getServiceToken() {
+        return uId;
+    }
+
+    private JobStatus(JobInfo job, int uId, boolean persisted, int numFailures) {
+        this.job = job;
+        this.uId = uId;
+        this.numFailures = numFailures;
+        this.persisted = persisted;
+    }
+
+    /** Create a newly scheduled job. */
+    public JobStatus(JobInfo job, int uId, boolean persisted) {
+        this(job, uId, persisted, 0);
+
+        final long elapsedNow = SystemClock.elapsedRealtime();
+
+        if (job.isPeriodic()) {
+            earliestRunTimeElapsedMillis = elapsedNow;
+            latestRunTimeElapsedMillis = elapsedNow + job.getIntervalMillis();
+        } else {
+            earliestRunTimeElapsedMillis = job.hasEarlyConstraint() ?
+                    elapsedNow + job.getMinLatencyMillis() : NO_EARLIEST_RUNTIME;
+            latestRunTimeElapsedMillis = job.hasLateConstraint() ?
+                    elapsedNow + job.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
+        }
+    }
+
+    /**
+     * Create a new JobStatus that was loaded from disk. We ignore the provided
+     * {@link android.app.job.JobInfo} time criteria because we can load a persisted periodic job
+     * from the {@link com.android.server.job.JobStore} and still want to respect its
+     * wallclock runtime rather than resetting it on every boot.
+     * We consider a freshly loaded job to no longer be in back-off.
+     */
+    public JobStatus(JobInfo job, int uId, long earliestRunTimeElapsedMillis,
+                      long latestRunTimeElapsedMillis) {
+        this(job, uId, true, 0);
+
+        this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
+        this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
+    }
+
+    /** Create a new job to be rescheduled with the provided parameters. */
+    public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis,
+                      long newLatestRuntimeElapsedMillis, int backoffAttempt) {
+        this(rescheduling.job, rescheduling.getUid(), rescheduling.isPersisted(), backoffAttempt);
+
+        earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
+        latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
+    }
+
+    public JobInfo getJob() {
+        return job;
+    }
+
+    public int getJobId() {
+        return job.getId();
+    }
+
+    public int getNumFailures() {
+        return numFailures;
+    }
+
+    public ComponentName getServiceComponent() {
+        return job.getService();
+    }
+
+    public int getUserId() {
+        return UserHandle.getUserId(uId);
+    }
+
+    public int getUid() {
+        return uId;
+    }
+
+    public PersistableBundle getExtras() {
+        return job.getExtras();
+    }
+
+    public boolean hasConnectivityConstraint() {
+        return job.getNetworkCapabilities() == JobInfo.NetworkType.ANY;
+    }
+
+    public boolean hasUnmeteredConstraint() {
+        return job.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED;
+    }
+
+    public boolean hasChargingConstraint() {
+        return job.isRequireCharging();
+    }
+
+    public boolean hasTimingDelayConstraint() {
+        return earliestRunTimeElapsedMillis != NO_EARLIEST_RUNTIME;
+    }
+
+    public boolean hasDeadlineConstraint() {
+        return latestRunTimeElapsedMillis != NO_LATEST_RUNTIME;
+    }
+
+    public boolean hasIdleConstraint() {
+        return job.isRequireDeviceIdle();
+    }
+
+    public long getEarliestRunTime() {
+        return earliestRunTimeElapsedMillis;
+    }
+
+    public long getLatestRunTimeElapsed() {
+        return latestRunTimeElapsedMillis;
+    }
+
+    public boolean isPersisted() {
+        return persisted;
+    }
+    /**
+     * @return Whether or not this job is ready to run, based on its requirements.
+     */
+    public synchronized boolean isReady() {
+        return (!hasChargingConstraint() || chargingConstraintSatisfied.get())
+                && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
+                && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
+                && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
+                && (!hasIdleConstraint() || idleConstraintSatisfied.get())
+                // Also ready if the deadline has expired - special case.
+                || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
+    }
+
+    public boolean matches(int uid, int jobId) {
+        return this.job.getId() == jobId && this.uId == uid;
+    }
+
+    @Override
+    public String toString() {
+        return String.valueOf(hashCode()).substring(0, 3) + ".."
+                + ":[" + job.getService().getPackageName() + ",jId=" + job.getId()
+                + ",R=(" + earliestRunTimeElapsedMillis + "," + latestRunTimeElapsedMillis + ")"
+                + ",N=" + job.getNetworkCapabilities() + ",C=" + job.isRequireCharging()
+                + ",I=" + job.isRequireDeviceIdle() + ",F=" + numFailures
+                + (isReady() ? "(READY)" : "")
+                + "]";
+    }
+    // Dumpsys infrastructure
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(this.toString());
+    }
+}
diff --git a/services/core/java/com/android/server/task/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
similarity index 70%
rename from services/core/java/com/android/server/task/controllers/StateController.java
rename to services/core/java/com/android/server/job/controllers/StateController.java
index a7f52f5..81658bf 100644
--- a/services/core/java/com/android/server/task/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -14,18 +14,18 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import android.content.Context;
 
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 
 /**
- * Incorporates shared controller logic between the various controllers of the TaskManager.
- * These are solely responsible for tracking a list of tasks, and notifying the TM when these
+ * Incorporates shared controller logic between the various controllers of the JobManager.
+ * These are solely responsible for tracking a list of jobs, and notifying the JM when these
  * are ready to run, or whether they must be stopped.
  */
 public abstract class StateController {
@@ -39,16 +39,16 @@
     }
 
     /**
-     * Implement the logic here to decide whether a task should be tracked by this controller.
-     * This logic is put here so the TaskManger can be completely agnostic of Controller logic.
+     * Implement the logic here to decide whether a job should be tracked by this controller.
+     * This logic is put here so the JobManger can be completely agnostic of Controller logic.
      * Also called when updating a task, so implementing controllers have to be aware of
      * preexisting tasks.
      */
-    public abstract void maybeStartTrackingTask(TaskStatus taskStatus);
+    public abstract void maybeStartTrackingJob(JobStatus jobStatus);
     /**
      * Remove task - this will happen if the task is cancelled, completed, etc.
      */
-    public abstract void maybeStopTrackingTask(TaskStatus taskStatus);
+    public abstract void maybeStopTrackingJob(JobStatus jobStatus);
 
     public abstract void dumpControllerState(PrintWriter pw);
 
diff --git a/services/core/java/com/android/server/task/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
similarity index 61%
rename from services/core/java/com/android/server/task/controllers/TimeController.java
rename to services/core/java/com/android/server/job/controllers/TimeController.java
index b75036c..e46226c 100644
--- a/services/core/java/com/android/server/task/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.task.controllers;
+package com.android.server.job.controllers;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -25,8 +25,8 @@
 import android.os.SystemClock;
 import android.util.Slog;
 
-import com.android.server.task.StateChangedListener;
-import com.android.server.task.TaskManagerService;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
 import java.util.Iterator;
@@ -35,35 +35,35 @@
 import java.util.ListIterator;
 
 /**
- * This class sets an alarm for the next expiring task, and determines whether a task's minimum
+ * This class sets an alarm for the next expiring job, and determines whether a job's minimum
  * delay has been satisfied.
  */
 public class TimeController extends StateController {
-    private static final String TAG = "TaskManager.Time";
-    private static final String ACTION_TASK_EXPIRED =
-            "android.content.taskmanager.TASK_DEADLINE_EXPIRED";
-    private static final String ACTION_TASK_DELAY_EXPIRED =
-            "android.content.taskmanager.TASK_DELAY_EXPIRED";
+    private static final String TAG = "JobScheduler.Time";
+    private static final String ACTION_JOB_EXPIRED =
+            "android.content.jobscheduler.JOB_DEADLINE_EXPIRED";
+    private static final String ACTION_JOB_DELAY_EXPIRED =
+            "android.content.jobscheduler.JOB_DELAY_EXPIRED";
 
-    /** Set an alarm for the next task expiry. */
+    /** Set an alarm for the next job expiry. */
     private final PendingIntent mDeadlineExpiredAlarmIntent;
-    /** Set an alarm for the next task delay expiry. This*/
+    /** Set an alarm for the next job delay expiry. This*/
     private final PendingIntent mNextDelayExpiredAlarmIntent;
     /** Constant time determining how near in the future we'll set an alarm for. */
     private static final long MIN_WAKEUP_INTERVAL_MILLIS = 15 * 1000;
 
-    private long mNextTaskExpiredElapsedMillis;
+    private long mNextJobExpiredElapsedMillis;
     private long mNextDelayExpiredElapsedMillis;
 
     private AlarmManager mAlarmService = null;
-    /** List of tracked tasks, sorted asc. by deadline */
-    private final List<TaskStatus> mTrackedTasks = new LinkedList<TaskStatus>();
+    /** List of tracked jobs, sorted asc. by deadline */
+    private final List<JobStatus> mTrackedJobs = new LinkedList<JobStatus>();
     /** Singleton. */
     private static TimeController mSingleton;
 
-    public static synchronized TimeController get(TaskManagerService taskManager) {
+    public static synchronized TimeController get(JobSchedulerService jms) {
         if (mSingleton == null) {
-            mSingleton = new TimeController(taskManager, taskManager.getContext());
+            mSingleton = new TimeController(jms, jms.getContext());
         }
         return mSingleton;
     }
@@ -72,66 +72,66 @@
         super(stateChangedListener, context);
         mDeadlineExpiredAlarmIntent =
                 PendingIntent.getBroadcast(mContext, 0 /* ignored */,
-                        new Intent(ACTION_TASK_EXPIRED), 0);
+                        new Intent(ACTION_JOB_EXPIRED), 0);
         mNextDelayExpiredAlarmIntent =
                 PendingIntent.getBroadcast(mContext, 0 /* ignored */,
-                        new Intent(ACTION_TASK_DELAY_EXPIRED), 0);
-        mNextTaskExpiredElapsedMillis = Long.MAX_VALUE;
+                        new Intent(ACTION_JOB_DELAY_EXPIRED), 0);
+        mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
 
         // Register BR for these intents.
-        IntentFilter intentFilter = new IntentFilter(ACTION_TASK_EXPIRED);
-        intentFilter.addAction(ACTION_TASK_DELAY_EXPIRED);
+        IntentFilter intentFilter = new IntentFilter(ACTION_JOB_EXPIRED);
+        intentFilter.addAction(ACTION_JOB_DELAY_EXPIRED);
         mContext.registerReceiver(mAlarmExpiredReceiver, intentFilter);
     }
 
     /**
-     * Check if the task has a timing constraint, and if so determine where to insert it in our
+     * Check if the job has a timing constraint, and if so determine where to insert it in our
      * list.
      */
     @Override
-    public synchronized void maybeStartTrackingTask(TaskStatus task) {
-        if (task.hasTimingDelayConstraint() || task.hasDeadlineConstraint()) {
-            maybeStopTrackingTask(task);
-            ListIterator<TaskStatus> it = mTrackedTasks.listIterator(mTrackedTasks.size());
+    public synchronized void maybeStartTrackingJob(JobStatus job) {
+        if (job.hasTimingDelayConstraint() || job.hasDeadlineConstraint()) {
+            maybeStopTrackingJob(job);
+            ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
             while (it.hasPrevious()) {
-                TaskStatus ts = it.previous();
-                if (ts.getLatestRunTimeElapsed() < task.getLatestRunTimeElapsed()) {
+                JobStatus ts = it.previous();
+                if (ts.getLatestRunTimeElapsed() < job.getLatestRunTimeElapsed()) {
                     // Insert
                     break;
                 }
             }
-            it.add(task);
+            it.add(job);
             maybeUpdateAlarms(
-                    task.hasTimingDelayConstraint() ? task.getEarliestRunTime() : Long.MAX_VALUE,
-                    task.hasDeadlineConstraint() ? task.getLatestRunTimeElapsed() : Long.MAX_VALUE);
+                    job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE,
+                    job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE);
         }
     }
 
     /**
-     * When we stop tracking a task, we only need to update our alarms if the task we're no longer
+     * When we stop tracking a job, we only need to update our alarms if the job we're no longer
      * tracking was the one our alarms were based off of.
      * Really an == comparison should be enough, but why play with fate? We'll do <=.
      */
     @Override
-    public synchronized void maybeStopTrackingTask(TaskStatus taskStatus) {
-        if (mTrackedTasks.remove(taskStatus)) {
+    public synchronized void maybeStopTrackingJob(JobStatus job) {
+        if (mTrackedJobs.remove(job)) {
             checkExpiredDelaysAndResetAlarm();
             checkExpiredDeadlinesAndResetAlarm();
         }
     }
 
     /**
-     * Determines whether this controller can stop tracking the given task.
-     * The controller is no longer interested in a task once its time constraint is satisfied, and
-     * the task's deadline is fulfilled - unlike other controllers a time constraint can't toggle
+     * Determines whether this controller can stop tracking the given job.
+     * The controller is no longer interested in a job once its time constraint is satisfied, and
+     * the job's deadline is fulfilled - unlike other controllers a time constraint can't toggle
      * back and forth.
      */
-    private boolean canStopTrackingTask(TaskStatus taskStatus) {
-        return (!taskStatus.hasTimingDelayConstraint() ||
-                taskStatus.timeDelayConstraintSatisfied.get()) &&
-                (!taskStatus.hasDeadlineConstraint() ||
-                        taskStatus.deadlineConstraintSatisfied.get());
+    private boolean canStopTrackingJob(JobStatus job) {
+        return (!job.hasTimingDelayConstraint() ||
+                job.timeDelayConstraintSatisfied.get()) &&
+                (!job.hasDeadlineConstraint() ||
+                        job.deadlineConstraintSatisfied.get());
     }
 
     private void ensureAlarmService() {
@@ -141,27 +141,27 @@
     }
 
     /**
-     * Checks list of tasks for ones that have an expired deadline, sending them to the TaskManager
+     * Checks list of jobs for ones that have an expired deadline, sending them to the JobScheduler
      * if so, removing them from this list, and updating the alarm for the next expiry time.
      */
     private synchronized void checkExpiredDeadlinesAndResetAlarm() {
         long nextExpiryTime = Long.MAX_VALUE;
         final long nowElapsedMillis = SystemClock.elapsedRealtime();
 
-        Iterator<TaskStatus> it = mTrackedTasks.iterator();
+        Iterator<JobStatus> it = mTrackedJobs.iterator();
         while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (!ts.hasDeadlineConstraint()) {
+            JobStatus job = it.next();
+            if (!job.hasDeadlineConstraint()) {
                 continue;
             }
-            final long taskDeadline = ts.getLatestRunTimeElapsed();
+            final long jobDeadline = job.getLatestRunTimeElapsed();
 
-            if (taskDeadline <= nowElapsedMillis) {
-                ts.deadlineConstraintSatisfied.set(true);
-                mStateChangedListener.onRunTaskNow(ts);
+            if (jobDeadline <= nowElapsedMillis) {
+                job.deadlineConstraintSatisfied.set(true);
+                mStateChangedListener.onRunJobNow(job);
                 it.remove();
             } else {  // Sorted by expiry time, so take the next one and stop.
-                nextExpiryTime = taskDeadline;
+                nextExpiryTime = jobDeadline;
                 break;
             }
         }
@@ -169,31 +169,31 @@
     }
 
     /**
-     * Handles alarm that notifies us that a task's delay has expired. Iterates through the list of
-     * tracked tasks and marks them as ready as appropriate.
+     * Handles alarm that notifies us that a job's delay has expired. Iterates through the list of
+     * tracked jobs and marks them as ready as appropriate.
      */
     private synchronized void checkExpiredDelaysAndResetAlarm() {
         final long nowElapsedMillis = SystemClock.elapsedRealtime();
         long nextDelayTime = Long.MAX_VALUE;
         boolean ready = false;
-        Iterator<TaskStatus> it = mTrackedTasks.iterator();
+        Iterator<JobStatus> it = mTrackedJobs.iterator();
         while (it.hasNext()) {
-            final TaskStatus ts = it.next();
-            if (!ts.hasTimingDelayConstraint()) {
+            final JobStatus job = it.next();
+            if (!job.hasTimingDelayConstraint()) {
                 continue;
             }
-            final long taskDelayTime = ts.getEarliestRunTime();
-            if (taskDelayTime <= nowElapsedMillis) {
-                ts.timeDelayConstraintSatisfied.set(true);
-                if (canStopTrackingTask(ts)) {
+            final long jobDelayTime = job.getEarliestRunTime();
+            if (jobDelayTime <= nowElapsedMillis) {
+                job.timeDelayConstraintSatisfied.set(true);
+                if (canStopTrackingJob(job)) {
                     it.remove();
                 }
-                if (ts.isReady()) {
+                if (job.isReady()) {
                     ready = true;
                 }
             } else {  // Keep going through list to get next delay time.
-                if (nextDelayTime > taskDelayTime) {
-                    nextDelayTime = taskDelayTime;
+                if (nextDelayTime > jobDelayTime) {
+                    nextDelayTime = jobDelayTime;
                 }
             }
         }
@@ -207,13 +207,13 @@
         if (delayExpiredElapsed < mNextDelayExpiredElapsedMillis) {
             setDelayExpiredAlarm(delayExpiredElapsed);
         }
-        if (deadlineExpiredElapsed < mNextTaskExpiredElapsedMillis) {
+        if (deadlineExpiredElapsed < mNextJobExpiredElapsedMillis) {
             setDeadlineExpiredAlarm(deadlineExpiredElapsed);
         }
     }
 
     /**
-     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a task's
+     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
      * delay will expire.
      * This alarm <b>will not</b> wake up the phone.
      */
@@ -228,7 +228,7 @@
     }
 
     /**
-     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a task's
+     * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
      * deadline will expire.
      * This alarm <b>will</b> wake up the phone.
      */
@@ -238,8 +238,8 @@
         if (alarmTimeElapsedMillis < earliestWakeupTimeElapsed) {
             alarmTimeElapsedMillis = earliestWakeupTimeElapsed;
         }
-        mNextTaskExpiredElapsedMillis = alarmTimeElapsedMillis;
-        updateAlarmWithPendingIntent(mDeadlineExpiredAlarmIntent, mNextTaskExpiredElapsedMillis);
+        mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis;
+        updateAlarmWithPendingIntent(mDeadlineExpiredAlarmIntent, mNextJobExpiredElapsedMillis);
     }
 
     private void updateAlarmWithPendingIntent(PendingIntent pi, long alarmTimeElapsed) {
@@ -260,11 +260,11 @@
             if (DEBUG) {
                 Slog.d(TAG, "Just received alarm: " + intent.getAction());
             }
-            // An task has just expired, so we run through the list of tasks that we have and
+            // A job has just expired, so we run through the list of jobs that we have and
             // notify our StateChangedListener.
-            if (ACTION_TASK_EXPIRED.equals(intent.getAction())) {
+            if (ACTION_JOB_EXPIRED.equals(intent.getAction())) {
                 checkExpiredDeadlinesAndResetAlarm();
-            } else if (ACTION_TASK_DELAY_EXPIRED.equals(intent.getAction())) {
+            } else if (ACTION_JOB_DELAY_EXPIRED.equals(intent.getAction())) {
                 checkExpiredDelaysAndResetAlarm();
             }
         }
@@ -276,10 +276,10 @@
         pw.println("Alarms (" + SystemClock.elapsedRealtime() + ")");
         pw.println(
                 "Next delay alarm in " + (mNextDelayExpiredElapsedMillis - nowElapsed)/1000 + "s");
-        pw.println("Next deadline alarm in " + (mNextTaskExpiredElapsedMillis - nowElapsed)/1000
+        pw.println("Next deadline alarm in " + (mNextJobExpiredElapsedMillis - nowElapsed)/1000
                 + "s");
         pw.println("Tracking:");
-        for (TaskStatus ts : mTrackedTasks) {
+        for (JobStatus ts : mTrackedJobs) {
             pw.println(String.valueOf(ts.hashCode()).substring(0, 3) + ".."
                     + ": (" + (ts.hasTimingDelayConstraint() ? ts.getEarliestRunTime() : "N/A")
                     + ", " + (ts.hasDeadlineConstraint() ?ts.getLatestRunTimeElapsed() : "N/A")
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 835b094..9ae8aed 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -949,6 +949,11 @@
         }
 
         @Override
+        public long getFlags() {
+            return mFlags;
+        }
+
+        @Override
         public void play() throws RemoteException {
             mSessionCb.play();
         }
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index aee7679..907eeb2 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -81,15 +81,15 @@
                     for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
                         out.writeUTF(LINK_ADDRESS_KEY);
                         out.writeUTF(linkAddr.getAddress().getHostAddress());
-                        out.writeInt(linkAddr.getNetworkPrefixLength());
+                        out.writeInt(linkAddr.getPrefixLength());
                     }
                     for (RouteInfo route : linkProperties.getRoutes()) {
                         out.writeUTF(GATEWAY_KEY);
-                        LinkAddress dest = route.getDestination();
+                        LinkAddress dest = route.getDestinationLinkAddress();
                         if (dest != null) {
                             out.writeInt(1);
                             out.writeUTF(dest.getAddress().getHostAddress());
-                            out.writeInt(dest.getNetworkPrefixLength());
+                            out.writeInt(dest.getPrefixLength());
                         } else {
                             out.writeInt(0);
                         }
@@ -100,7 +100,7 @@
                             out.writeInt(0);
                         }
                     }
-                    for (InetAddress inetAddr : linkProperties.getDnses()) {
+                    for (InetAddress inetAddr : linkProperties.getDnsServers()) {
                         out.writeUTF(DNS_KEY);
                         out.writeUTF(inetAddr.getHostAddress());
                     }
@@ -232,7 +232,7 @@
                             }
                             linkProperties.addRoute(new RouteInfo(dest, gateway));
                         } else if (key.equals(DNS_KEY)) {
-                            linkProperties.addDns(
+                            linkProperties.addDnsServer(
                                     NetworkUtils.numericToInetAddress(in.readUTF()));
                         } else if (key.equals(PROXY_SETTINGS_KEY)) {
                             proxySettings = ProxySettings.valueOf(in.readUTF());
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 386402b..05aa2c7 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2264,16 +2264,15 @@
 
     // lock on mNotificationList
     int indexOfNotificationLocked(String key) {
-        NotificationRecord r = mNotificationsByKey.get(key);
-        if (r == null) {
-            return -1;
+        final int N = mNotificationList.size();
+        for (int i = 0; i < N; i++) {
+            if (key.equals(mNotificationList.get(i).getKey())) {
+                return i;
+            }
         }
-        int index = Collections.binarySearch(mNotificationList, r, mRankingComparator);
-        // Guarantee to return -1 when not found.
-        return (index >= 0) ? index : -1;
+        return -1;
     }
 
-
     private void updateNotificationPulse() {
         synchronized (mNotificationList) {
             updateLightsLocked();
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 50a32c4..b95db9cb 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -18,6 +18,7 @@
 
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
+import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -88,6 +89,10 @@
     private static final Set<String> ALARM_PACKAGES = new HashSet<String>(Arrays.asList(
             "com.google.android.deskclock"
             ));
+    private static final Set<String> SYSTEM_PACKAGES = new HashSet<String>(Arrays.asList(
+            "android",
+            "com.android.systemui"
+            ));
 
     public ZenModeHelper(Context context, Handler handler) {
         mContext = context;
@@ -130,6 +135,9 @@
                 // notifications never transition from not intercepted to intercepted
                 return false;
             }
+            if (isSystem(record)) {
+                return false;
+            }
             if (isAlarm(record)) {
                 return false;
             }
@@ -239,6 +247,11 @@
         }
     }
 
+    private boolean isSystem(NotificationRecord record) {
+        return SYSTEM_PACKAGES.contains(record.sbn.getPackageName())
+                && Notification.CATEGORY_SYSTEM.equals(record.getNotification().category);
+    }
+
     private boolean isAlarm(NotificationRecord record) {
         return ALARM_PACKAGES.contains(record.sbn.getPackageName());
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0c094e8..407ecb8 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4988,6 +4988,7 @@
                     mResolveActivity.packageName = mAndroidApplication.packageName;
                     mResolveActivity.processName = "system:ui";
                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
                     mResolveActivity.exported = true;
@@ -10203,7 +10204,7 @@
         synchronized (mPackages) {
             // Check whether the newly-scanned package wants to define an already-defined perm
             int N = pkg.permissions.size();
-            for (int i = 0; i < N; i++) {
+            for (int i = N-1; i >= 0; i--) {
                 PackageParser.Permission perm = pkg.permissions.get(i);
                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
                 if (bp != null) {
@@ -10211,13 +10212,23 @@
                     // also includes the "updating the same package" case, of course.
                     if (compareSignatures(bp.packageSetting.signatures.mSignatures,
                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
-                        Slog.w(TAG, "Package " + pkg.packageName
-                                + " attempting to redeclare permission " + perm.info.name
-                                + " already owned by " + bp.sourcePackage);
-                        res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
-                        res.origPermission = perm.info.name;
-                        res.origPackage = bp.sourcePackage;
-                        return;
+                        // If the owning package is the system itself, we log but allow
+                        // install to proceed; we fail the install on all other permission
+                        // redefinitions.
+                        if (!bp.sourcePackage.equals("android")) {
+                            Slog.w(TAG, "Package " + pkg.packageName
+                                    + " attempting to redeclare permission " + perm.info.name
+                                    + " already owned by " + bp.sourcePackage);
+                            res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
+                            res.origPermission = perm.info.name;
+                            res.origPackage = bp.sourcePackage;
+                            return;
+                        } else {
+                            Slog.w(TAG, "Package " + pkg.packageName
+                                    + " attempting to redeclare system permission "
+                                    + perm.info.name + "; ignoring new declaration");
+                            pkg.permissions.remove(i);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index d8671d9..fb4b8f0 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -409,6 +409,9 @@
     // Current state of the low power mode setting.
     private boolean mLowPowerModeSetting;
 
+    // Current state of whether the settings are allowing auto low power mode.
+    private boolean mAutoLowPowerModeEnabled;
+
     // True if the battery level is currently considered low.
     private boolean mBatteryLevelLow;
 
@@ -558,6 +561,9 @@
             resolver.registerContentObserver(Settings.Global.getUriFor(
                     Settings.Global.LOW_POWER_MODE),
                     false, mSettingsObserver, UserHandle.USER_ALL);
+            resolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+                    false, mSettingsObserver, UserHandle.USER_ALL);
             // Go.
             readConfigurationLocked();
             updateSettingsLocked();
@@ -645,8 +651,12 @@
 
         final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE, 0) != 0;
-        if (lowPowerModeEnabled != mLowPowerModeSetting) {
+        final boolean autoLowPowerModeEnabled = Settings.Global.getInt(resolver,
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15) != 0;
+        if (lowPowerModeEnabled != mLowPowerModeSetting
+                || autoLowPowerModeEnabled != mAutoLowPowerModeEnabled) {
             mLowPowerModeSetting = lowPowerModeEnabled;
+            mAutoLowPowerModeEnabled = autoLowPowerModeEnabled;
             updateLowPowerModeLocked();
         }
 
@@ -654,7 +664,8 @@
     }
 
     void updateLowPowerModeLocked() {
-        final boolean lowPowerModeEnabled = mLowPowerModeSetting || mBatteryLevelLow;
+        final boolean lowPowerModeEnabled = !mIsPowered
+                && (mLowPowerModeSetting || (mAutoLowPowerModeEnabled && mBatteryLevelLow));
         if (mLowPowerModeEnabled != lowPowerModeEnabled) {
             mLowPowerModeEnabled = lowPowerModeEnabled;
             powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
@@ -1197,7 +1208,7 @@
                 }
             }
 
-            if (oldLevelLow != mBatteryLevelLow) {
+            if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
                 updateLowPowerModeLocked();
             }
         }
@@ -2168,6 +2179,8 @@
             pw.println("  mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
             pw.println("  mSandmanScheduled=" + mSandmanScheduled);
             pw.println("  mSandmanSummoned=" + mSandmanSummoned);
+            pw.println("  mLowPowerModeEnabled=" + mLowPowerModeEnabled);
+            pw.println("  mBatteryLevelLow=" + mBatteryLevelLow);
             pw.println("  mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
             pw.println("  mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
             pw.println("  mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
@@ -2204,6 +2217,8 @@
             pw.println("  mDreamsEnabledSetting=" + mDreamsEnabledSetting);
             pw.println("  mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
             pw.println("  mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
+            pw.println("  mLowPowerModeSetting=" + mLowPowerModeSetting);
+            pw.println("  mAutoLowPowerModeEnabled=" + mAutoLowPowerModeEnabled);
             pw.println("  mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
             pw.println("  mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
             pw.println("  mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);
diff --git a/services/core/java/com/android/server/task/StateChangedListener.java b/services/core/java/com/android/server/task/StateChangedListener.java
deleted file mode 100644
index ab5cc7c..0000000
--- a/services/core/java/com/android/server/task/StateChangedListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task;
-
-import com.android.server.task.controllers.TaskStatus;
-
-/**
- * Interface through which a {@link com.android.server.task.controllers.StateController} informs
- * the {@link com.android.server.task.TaskManagerService} that there are some tasks potentially
- * ready to be run.
- */
-public interface StateChangedListener {
-    /**
-     * Called by the controller to notify the TaskManager that it should check on the state of a
-     * task.
-     */
-    public void onControllerStateChanged();
-
-    /**
-     * Called by the controller to notify the TaskManager that regardless of the state of the task,
-     * it must be run immediately.
-     * @param taskStatus The state of the task which is to be run immediately.
-     */
-    public void onRunTaskNow(TaskStatus taskStatus);
-}
diff --git a/services/core/java/com/android/server/task/TaskManagerService.java b/services/core/java/com/android/server/task/TaskManagerService.java
deleted file mode 100644
index 0c55a1d..0000000
--- a/services/core/java/com/android/server/task/TaskManagerService.java
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import android.app.task.ITaskManager;
-import android.app.task.Task;
-import android.app.task.TaskManager;
-import android.content.BroadcastReceiver;
-import android.app.task.TaskService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ServiceInfo;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.server.task.controllers.BatteryController;
-import com.android.server.task.controllers.ConnectivityController;
-import com.android.server.task.controllers.IdleController;
-import com.android.server.task.controllers.StateController;
-import com.android.server.task.controllers.TaskStatus;
-import com.android.server.task.controllers.TimeController;
-
-import java.util.LinkedList;
-
-/**
- * Responsible for taking tasks representing work to be performed by a client app, and determining
- * based on the criteria specified when that task should be run against the client application's
- * endpoint.
- * Implements logic for scheduling, and rescheduling tasks. The TaskManagerService knows nothing
- * about constraints, or the state of active tasks. It receives callbacks from the various
- * controllers and completed tasks and operates accordingly.
- *
- * Note on locking: Any operations that manipulate {@link #mTasks} need to lock on that object.
- * Any function with the suffix 'Locked' also needs to lock on {@link #mTasks}.
- * @hide
- */
-public class TaskManagerService extends com.android.server.SystemService
-        implements StateChangedListener, TaskCompletedListener, TaskMapReadFinishedListener {
-    // TODO: Switch this off for final version.
-    static final boolean DEBUG = true;
-    /** The number of concurrent tasks we run at one time. */
-    private static final int MAX_TASK_CONTEXTS_COUNT = 3;
-    static final String TAG = "TaskManager";
-    /** Master list of tasks. */
-    private final TaskStore mTasks;
-
-    static final int MSG_TASK_EXPIRED = 0;
-    static final int MSG_CHECK_TASKS = 1;
-
-    // Policy constants
-    /**
-     * Minimum # of idle tasks that must be ready in order to force the TM to schedule things
-     * early.
-     */
-    private static final int MIN_IDLE_COUNT = 1;
-    /**
-     * Minimum # of connectivity tasks that must be ready in order to force the TM to schedule
-     * things early.
-     */
-    private static final int MIN_CONNECTIVITY_COUNT = 2;
-    /**
-     * Minimum # of tasks (with no particular constraints) for which the TM will be happy running
-     * some work early.
-     */
-    private static final int MIN_READY_TASKS_COUNT = 4;
-
-    /**
-     * Track Services that have currently active or pending tasks. The index is provided by
-     * {@link TaskStatus#getServiceToken()}
-     */
-    private final List<TaskServiceContext> mActiveServices = new LinkedList<TaskServiceContext>();
-    /** List of controllers that will notify this service of updates to tasks. */
-    private List<StateController> mControllers;
-    /**
-     * Queue of pending tasks. The TaskServiceContext class will receive tasks from this list
-     * when ready to execute them.
-     */
-    private final LinkedList<TaskStatus> mPendingTasks = new LinkedList<TaskStatus>();
-
-    private final TaskHandler mHandler;
-    private final TaskManagerStub mTaskManagerStub;
-    /**
-     * Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we
-     * still clean up. On reinstall the package will have a new uid.
-     */
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Slog.d(TAG, "Receieved: " + intent.getAction());
-            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
-                int uidRemoved = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                if (DEBUG) {
-                    Slog.d(TAG, "Removing jobs for uid: " + uidRemoved);
-                }
-                cancelTasksForUid(uidRemoved);
-            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
-                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (DEBUG) {
-                    Slog.d(TAG, "Removing jobs for user: " + userId);
-                }
-                cancelTasksForUser(userId);
-            }
-        }
-    };
-
-    /**
-     * Entry point from client to schedule the provided task.
-     * This cancels the task if it's already been scheduled, and replaces it with the one provided.
-     * @param task Task object containing execution parameters
-     * @param uId The package identifier of the application this task is for.
-     * @param canPersistTask Whether or not the client has the appropriate permissions for
-     *                       persisting this task.
-     * @return Result of this operation. See <code>TaskManager#RESULT_*</code> return codes.
-     */
-    public int schedule(Task task, int uId, boolean canPersistTask) {
-        TaskStatus taskStatus = new TaskStatus(task, uId, canPersistTask);
-        cancelTask(uId, task.getId());
-        startTrackingTask(taskStatus);
-        return TaskManager.RESULT_SUCCESS;
-    }
-
-    public List<Task> getPendingTasks(int uid) {
-        ArrayList<Task> outList = new ArrayList<Task>();
-        synchronized (mTasks) {
-            for (TaskStatus ts : mTasks.getTasks()) {
-                if (ts.getUid() == uid) {
-                    outList.add(ts.getTask());
-                }
-            }
-        }
-        return outList;
-    }
-
-    private void cancelTasksForUser(int userHandle) {
-        synchronized (mTasks) {
-            List<TaskStatus> tasksForUser = mTasks.getTasksByUser(userHandle);
-            for (TaskStatus toRemove : tasksForUser) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Cancelling: " + toRemove);
-                }
-                cancelTaskLocked(toRemove);
-            }
-        }
-    }
-
-    /**
-     * Entry point from client to cancel all tasks originating from their uid.
-     * This will remove the task from the master list, and cancel the task if it was staged for
-     * execution or being executed.
-     * @param uid To check against for removal of a task.
-     */
-    public void cancelTasksForUid(int uid) {
-        // Remove from master list.
-        synchronized (mTasks) {
-            List<TaskStatus> tasksForUid = mTasks.getTasksByUid(uid);
-            for (TaskStatus toRemove : tasksForUid) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Cancelling: " + toRemove);
-                }
-                cancelTaskLocked(toRemove);
-            }
-        }
-    }
-
-    /**
-     * Entry point from client to cancel the task corresponding to the taskId provided.
-     * This will remove the task from the master list, and cancel the task if it was staged for
-     * execution or being executed.
-     * @param uid Uid of the calling client.
-     * @param taskId Id of the task, provided at schedule-time.
-     */
-    public void cancelTask(int uid, int taskId) {
-        TaskStatus toCancel;
-        synchronized (mTasks) {
-            toCancel = mTasks.getTaskByUidAndTaskId(uid, taskId);
-            if (toCancel != null) {
-                cancelTaskLocked(toCancel);
-            }
-        }
-    }
-
-    private void cancelTaskLocked(TaskStatus cancelled) {
-        // Remove from store.
-        stopTrackingTask(cancelled);
-        // Remove from pending queue.
-        mPendingTasks.remove(cancelled);
-        // Cancel if running.
-        stopTaskOnServiceContextLocked(cancelled);
-    }
-
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public TaskManagerService(Context context) {
-        super(context);
-        // Create the controllers.
-        mControllers = new LinkedList<StateController>();
-        mControllers.add(ConnectivityController.get(this));
-        mControllers.add(TimeController.get(this));
-        mControllers.add(IdleController.get(this));
-        mControllers.add(BatteryController.get(this));
-
-        mHandler = new TaskHandler(context.getMainLooper());
-        mTaskManagerStub = new TaskManagerStub();
-        // Create the "runners".
-        for (int i = 0; i < MAX_TASK_CONTEXTS_COUNT; i++) {
-            mActiveServices.add(
-                    new TaskServiceContext(this, context.getMainLooper()));
-        }
-        mTasks = TaskStore.initAndGet(this);
-    }
-
-    @Override
-    public void onStart() {
-        publishBinderService(Context.TASK_SERVICE, mTaskManagerStub);
-    }
-
-    @Override
-    public void onBootPhase(int phase) {
-        if (PHASE_SYSTEM_SERVICES_READY == phase) {
-            // Register br for package removals and user removals.
-            final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addDataScheme("package");
-            getContext().registerReceiverAsUser(
-                    mBroadcastReceiver, UserHandle.ALL, filter, null, null);
-            final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED);
-            getContext().registerReceiverAsUser(
-                    mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);
-        }
-    }
-
-    /**
-     * Called when we have a task status object that we need to insert in our
-     * {@link com.android.server.task.TaskStore}, and make sure all the relevant controllers know
-     * about.
-     */
-    private void startTrackingTask(TaskStatus taskStatus) {
-        boolean update;
-        synchronized (mTasks) {
-            update = mTasks.add(taskStatus);
-        }
-        for (StateController controller : mControllers) {
-            if (update) {
-                controller.maybeStopTrackingTask(taskStatus);
-            }
-            controller.maybeStartTrackingTask(taskStatus);
-        }
-    }
-
-    /**
-     * Called when we want to remove a TaskStatus object that we've finished executing. Returns the
-     * object removed.
-     */
-    private boolean stopTrackingTask(TaskStatus taskStatus) {
-        boolean removed;
-        synchronized (mTasks) {
-            // Remove from store as well as controllers.
-            removed = mTasks.remove(taskStatus);
-        }
-        if (removed) {
-            for (StateController controller : mControllers) {
-                controller.maybeStopTrackingTask(taskStatus);
-            }
-        }
-        return removed;
-    }
-
-    private boolean stopTaskOnServiceContextLocked(TaskStatus ts) {
-        for (TaskServiceContext tsc : mActiveServices) {
-            final TaskStatus executing = tsc.getRunningTask();
-            if (executing != null && executing.matches(ts.getUid(), ts.getTaskId())) {
-                tsc.cancelExecutingTask();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @param ts TaskStatus we are querying against.
-     * @return Whether or not the task represented by the status object is currently being run or
-     * is pending.
-     */
-    private boolean isCurrentlyActiveLocked(TaskStatus ts) {
-        for (TaskServiceContext serviceContext : mActiveServices) {
-            final TaskStatus running = serviceContext.getRunningTask();
-            if (running != null && running.matches(ts.getUid(), ts.getTaskId())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * A task is rescheduled with exponential back-off if the client requests this from their
-     * execution logic.
-     * A caveat is for idle-mode tasks, for which the idle-mode constraint will usurp the
-     * timeliness of the reschedule. For an idle-mode task, no deadline is given.
-     * @param failureToReschedule Provided task status that we will reschedule.
-     * @return A newly instantiated TaskStatus with the same constraints as the last task except
-     * with adjusted timing constraints.
-     */
-    private TaskStatus getRescheduleTaskForFailure(TaskStatus failureToReschedule) {
-        final long elapsedNowMillis = SystemClock.elapsedRealtime();
-        final Task task = failureToReschedule.getTask();
-
-        final long initialBackoffMillis = task.getInitialBackoffMillis();
-        final int backoffAttempt = failureToReschedule.getNumFailures() + 1;
-        long newEarliestRuntimeElapsed = elapsedNowMillis;
-
-        switch (task.getBackoffPolicy()) {
-            case Task.BackoffPolicy.LINEAR:
-                newEarliestRuntimeElapsed += initialBackoffMillis * backoffAttempt;
-                break;
-            default:
-                if (DEBUG) {
-                    Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential.");
-                }
-            case Task.BackoffPolicy.EXPONENTIAL:
-                newEarliestRuntimeElapsed +=
-                        Math.pow(initialBackoffMillis * 0.001, backoffAttempt) * 1000;
-                break;
-        }
-        newEarliestRuntimeElapsed =
-                Math.min(newEarliestRuntimeElapsed, Task.MAX_BACKOFF_DELAY_MILLIS);
-        return new TaskStatus(failureToReschedule, newEarliestRuntimeElapsed,
-                TaskStatus.NO_LATEST_RUNTIME, backoffAttempt);
-    }
-
-    /**
-     * Called after a periodic has executed so we can to re-add it. We take the last execution time
-     * of the task to be the time of completion (i.e. the time at which this function is called).
-     * This could be inaccurate b/c the task can run for as long as
-     * {@link com.android.server.task.TaskServiceContext#EXECUTING_TIMESLICE_MILLIS}, but will lead
-     * to underscheduling at least, rather than if we had taken the last execution time to be the
-     * start of the execution.
-     * @return A new task representing the execution criteria for this instantiation of the
-     * recurring task.
-     */
-    private TaskStatus getRescheduleTaskForPeriodic(TaskStatus periodicToReschedule) {
-        final long elapsedNow = SystemClock.elapsedRealtime();
-        // Compute how much of the period is remaining.
-        long runEarly = Math.max(periodicToReschedule.getLatestRunTimeElapsed() - elapsedNow, 0);
-        long newEarliestRunTimeElapsed = elapsedNow + runEarly;
-        long period = periodicToReschedule.getTask().getIntervalMillis();
-        long newLatestRuntimeElapsed = newEarliestRunTimeElapsed + period;
-
-        if (DEBUG) {
-            Slog.v(TAG, "Rescheduling executed periodic. New execution window [" +
-                    newEarliestRunTimeElapsed/1000 + ", " + newLatestRuntimeElapsed/1000 + "]s");
-        }
-        return new TaskStatus(periodicToReschedule, newEarliestRunTimeElapsed,
-                newLatestRuntimeElapsed, 0 /* backoffAttempt */);
-    }
-
-    // TaskCompletedListener implementations.
-
-    /**
-     * A task just finished executing. We fetch the
-     * {@link com.android.server.task.controllers.TaskStatus} from the store and depending on
-     * whether we want to reschedule we readd it to the controllers.
-     * @param taskStatus Completed task.
-     * @param needsReschedule Whether the implementing class should reschedule this task.
-     */
-    @Override
-    public void onTaskCompleted(TaskStatus taskStatus, boolean needsReschedule) {
-        if (DEBUG) {
-            Slog.d(TAG, "Completed " + taskStatus + ", reschedule=" + needsReschedule);
-        }
-        if (!stopTrackingTask(taskStatus)) {
-            if (DEBUG) {
-                Slog.e(TAG, "Error removing task: could not find task to remove. Was task " +
-                        "removed while executing?");
-            }
-            return;
-        }
-        if (needsReschedule) {
-            TaskStatus rescheduled = getRescheduleTaskForFailure(taskStatus);
-            startTrackingTask(rescheduled);
-        } else if (taskStatus.getTask().isPeriodic()) {
-            TaskStatus rescheduledPeriodic = getRescheduleTaskForPeriodic(taskStatus);
-            startTrackingTask(rescheduledPeriodic);
-        }
-        mHandler.obtainMessage(MSG_CHECK_TASKS).sendToTarget();
-    }
-
-    // StateChangedListener implementations.
-
-    /**
-     * Off-board work to our handler thread as quickly as possible, b/c this call is probably being
-     * made on the main thread.
-     * For now this takes the task and if it's ready to run it will run it. In future we might not
-     * provide the task, so that the StateChangedListener has to run through its list of tasks to
-     * see which are ready. This will further decouple the controllers from the execution logic.
-     */
-    @Override
-    public void onControllerStateChanged() {
-        // Post a message to to run through the list of tasks and start/stop any that are eligible.
-        mHandler.obtainMessage(MSG_CHECK_TASKS).sendToTarget();
-    }
-
-    @Override
-    public void onRunTaskNow(TaskStatus taskStatus) {
-        mHandler.obtainMessage(MSG_TASK_EXPIRED, taskStatus).sendToTarget();
-    }
-
-    /**
-     * Disk I/O is finished, take the list of tasks we read from disk and add them to our
-     * {@link TaskStore}.
-     * This is run on the {@link com.android.server.IoThread} instance, which is a separate thread,
-     * and is called once at boot.
-     */
-    @Override
-    public void onTaskMapReadFinished(List<TaskStatus> tasks) {
-        synchronized (mTasks) {
-            for (TaskStatus ts : tasks) {
-                if (mTasks.containsTaskIdForUid(ts.getTaskId(), ts.getUid())) {
-                    // An app with BOOT_COMPLETED *might* have decided to reschedule their task, in
-                    // the same amount of time it took us to read it from disk. If this is the case
-                    // we leave it be.
-                    continue;
-                }
-                startTrackingTask(ts);
-            }
-        }
-    }
-
-    private class TaskHandler extends Handler {
-
-        public TaskHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message message) {
-            switch (message.what) {
-                case MSG_TASK_EXPIRED:
-                    synchronized (mTasks) {
-                        TaskStatus runNow = (TaskStatus) message.obj;
-                        if (!mPendingTasks.contains(runNow)) {
-                            mPendingTasks.add(runNow);
-                        }
-                    }
-                    queueReadyTasksForExecutionH();
-                    break;
-                case MSG_CHECK_TASKS:
-                    // Check the list of tasks and run some of them if we feel inclined.
-                    maybeQueueReadyTasksForExecutionH();
-                    break;
-            }
-            maybeRunPendingTasksH();
-            // Don't remove TASK_EXPIRED in case one came along while processing the queue.
-            removeMessages(MSG_CHECK_TASKS);
-        }
-
-        /**
-         * Run through list of tasks and execute all possible - at least one is expired so we do
-         * as many as we can.
-         */
-        private void queueReadyTasksForExecutionH() {
-            synchronized (mTasks) {
-                for (TaskStatus ts : mTasks.getTasks()) {
-                    if (isReadyToBeExecutedLocked(ts)) {
-                        mPendingTasks.add(ts);
-                    } else if (isReadyToBeCancelledLocked(ts)) {
-                        stopTaskOnServiceContextLocked(ts);
-                    }
-                }
-            }
-        }
-
-        /**
-         * The state of at least one task has changed. Here is where we could enforce various
-         * policies on when we want to execute tasks.
-         * Right now the policy is such:
-         * If >1 of the ready tasks is idle mode we send all of them off
-         * if more than 2 network connectivity tasks are ready we send them all off.
-         * If more than 4 tasks total are ready we send them all off.
-         * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
-         */
-        private void maybeQueueReadyTasksForExecutionH() {
-            synchronized (mTasks) {
-                int idleCount = 0;
-                int backoffCount = 0;
-                int connectivityCount = 0;
-                List<TaskStatus> runnableTasks = new ArrayList<TaskStatus>();
-                for (TaskStatus ts : mTasks.getTasks()) {
-                    if (isReadyToBeExecutedLocked(ts)) {
-                        if (ts.getNumFailures() > 0) {
-                            backoffCount++;
-                        }
-                        if (ts.hasIdleConstraint()) {
-                            idleCount++;
-                        }
-                        if (ts.hasConnectivityConstraint() || ts.hasUnmeteredConstraint()) {
-                            connectivityCount++;
-                        }
-                        runnableTasks.add(ts);
-                    } else if (isReadyToBeCancelledLocked(ts)) {
-                        stopTaskOnServiceContextLocked(ts);
-                    }
-                }
-                if (backoffCount > 0 || idleCount >= MIN_IDLE_COUNT ||
-                        connectivityCount >= MIN_CONNECTIVITY_COUNT ||
-                        runnableTasks.size() >= MIN_READY_TASKS_COUNT) {
-                    for (TaskStatus ts : runnableTasks) {
-                        mPendingTasks.add(ts);
-                    }
-                }
-            }
-        }
-
-        /**
-         * Criteria for moving a job into the pending queue:
-         *      - It's ready.
-         *      - It's not pending.
-         *      - It's not already running on a TSC.
-         */
-        private boolean isReadyToBeExecutedLocked(TaskStatus ts) {
-              return ts.isReady() && !mPendingTasks.contains(ts) && !isCurrentlyActiveLocked(ts);
-        }
-
-        /**
-         * Criteria for cancelling an active job:
-         *      - It's not ready
-         *      - It's running on a TSC.
-         */
-        private boolean isReadyToBeCancelledLocked(TaskStatus ts) {
-            return !ts.isReady() && isCurrentlyActiveLocked(ts);
-        }
-
-        /**
-         * Reconcile jobs in the pending queue against available execution contexts.
-         * A controller can force a task into the pending queue even if it's already running, but
-         * here is where we decide whether to actually execute it.
-         */
-        private void maybeRunPendingTasksH() {
-            synchronized (mTasks) {
-                Iterator<TaskStatus> it = mPendingTasks.iterator();
-                while (it.hasNext()) {
-                    TaskStatus nextPending = it.next();
-                    TaskServiceContext availableContext = null;
-                    for (TaskServiceContext tsc : mActiveServices) {
-                        final TaskStatus running = tsc.getRunningTask();
-                        if (running != null && running.matches(nextPending.getUid(),
-                                nextPending.getTaskId())) {
-                            // Already running this tId for this uId, skip.
-                            availableContext = null;
-                            break;
-                        }
-                        if (tsc.isAvailable()) {
-                            availableContext = tsc;
-                        }
-                    }
-                    if (availableContext != null) {
-                        if (!availableContext.executeRunnableTask(nextPending)) {
-                            if (DEBUG) {
-                                Slog.d(TAG, "Error executing " + nextPending);
-                            }
-                            mTasks.remove(nextPending);
-                        }
-                        it.remove();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Binder stub trampoline implementation
-     */
-    final class TaskManagerStub extends ITaskManager.Stub {
-        /** Cache determination of whether a given app can persist tasks
-         * key is uid of the calling app; value is undetermined/true/false
-         */
-        private final SparseArray<Boolean> mPersistCache = new SparseArray<Boolean>();
-
-        // Enforce that only the app itself (or shared uid participant) can schedule a
-        // task that runs one of the app's services, as well as verifying that the
-        // named service properly requires the BIND_TASK_SERVICE permission
-        private void enforceValidJobRequest(int uid, Task job) {
-            final PackageManager pm = getContext().getPackageManager();
-            final ComponentName service = job.getService();
-            try {
-                ServiceInfo si = pm.getServiceInfo(service, 0);
-                if (si.applicationInfo.uid != uid) {
-                    throw new IllegalArgumentException("uid " + uid +
-                            " cannot schedule job in " + service.getPackageName());
-                }
-                if (!TaskService.PERMISSION_BIND.equals(si.permission)) {
-                    throw new IllegalArgumentException("Scheduled service " + service
-                            + " does not require android.permission.BIND_TASK_SERVICE permission");
-                }
-            } catch (NameNotFoundException e) {
-                throw new IllegalArgumentException("No such service: " + service);
-            }
-        }
-
-        private boolean canPersistJobs(int pid, int uid) {
-            // If we get this far we're good to go; all we need to do now is check
-            // whether the app is allowed to persist its scheduled work.
-            final boolean canPersist;
-            synchronized (mPersistCache) {
-                Boolean cached = mPersistCache.get(uid);
-                if (cached != null) {
-                    canPersist = cached.booleanValue();
-                } else {
-                    // Persisting tasks is tantamount to running at boot, so we permit
-                    // it when the app has declared that it uses the RECEIVE_BOOT_COMPLETED
-                    // permission
-                    int result = getContext().checkPermission(
-                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED, pid, uid);
-                    canPersist = (result == PackageManager.PERMISSION_GRANTED);
-                    mPersistCache.put(uid, canPersist);
-                }
-            }
-            return canPersist;
-        }
-
-        // ITaskManager implementation
-        @Override
-        public int schedule(Task task) throws RemoteException {
-            if (DEBUG) {
-                Slog.d(TAG, "Scheduling task: " + task);
-            }
-            final int pid = Binder.getCallingPid();
-            final int uid = Binder.getCallingUid();
-
-            enforceValidJobRequest(uid, task);
-            final boolean canPersist = canPersistJobs(pid, uid);
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                return TaskManagerService.this.schedule(task, uid, canPersist);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        @Override
-        public List<Task> getAllPendingTasks() throws RemoteException {
-            final int uid = Binder.getCallingUid();
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                return TaskManagerService.this.getPendingTasks(uid);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        @Override
-        public void cancelAll() throws RemoteException {
-            final int uid = Binder.getCallingUid();
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                TaskManagerService.this.cancelTasksForUid(uid);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        @Override
-        public void cancel(int taskId) throws RemoteException {
-            final int uid = Binder.getCallingUid();
-
-            long ident = Binder.clearCallingIdentity();
-            try {
-                TaskManagerService.this.cancelTask(uid, taskId);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        /**
-         * "dumpsys" infrastructure
-         */
-        @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
-            long identityToken = Binder.clearCallingIdentity();
-            try {
-                TaskManagerService.this.dumpInternal(pw);
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-    };
-
-    void dumpInternal(PrintWriter pw) {
-        synchronized (mTasks) {
-            pw.println("Registered tasks:");
-            if (mTasks.size() > 0) {
-                for (TaskStatus ts : mTasks.getTasks()) {
-                    ts.dump(pw, "  ");
-                }
-            } else {
-                pw.println();
-                pw.println("No tasks scheduled.");
-            }
-            for (StateController controller : mControllers) {
-                pw.println();
-                controller.dumpControllerState(pw);
-            }
-            pw.println();
-            pw.println("Pending");
-            for (TaskStatus taskStatus : mPendingTasks) {
-                pw.println(taskStatus.hashCode());
-            }
-            pw.println();
-            pw.println("Active jobs:");
-            for (TaskServiceContext tsc : mActiveServices) {
-                if (tsc.isAvailable()) {
-                    continue;
-                } else {
-                    pw.println(tsc.getRunningTask().hashCode() + " for: " +
-                            (SystemClock.elapsedRealtime()
-                                    - tsc.getExecutionStartTimeElapsed())/1000 + "s " +
-                            "timeout: " + tsc.getTimeoutElapsed());
-                }
-            }
-        }
-        pw.println();
-    }
-}
diff --git a/services/core/java/com/android/server/task/TaskStore.java b/services/core/java/com/android/server/task/TaskStore.java
deleted file mode 100644
index 9e095e7..0000000
--- a/services/core/java/com/android/server/task/TaskStore.java
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task;
-
-import android.content.ComponentName;
-import android.app.task.Task;
-import android.content.Context;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.AtomicFile;
-import android.util.ArraySet;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.Xml;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.server.IoThread;
-import com.android.server.task.controllers.TaskStatus;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-/**
- * Maintain a list of classes, and accessor methods/logic for these tasks.
- * This class offers the following functionality:
- *     - When a task is added, it will determine if the task requirements have changed (update) and
- *       whether the controllers need to be updated.
- *     - Persists Tasks, figures out when to to rewrite the Task to disk.
- *     - Handles rescheduling of tasks.
- *       - When a periodic task is executed and must be re-added.
- *       - When a task fails and the client requests that it be retried with backoff.
- *       - This class <strong>is not</strong> thread-safe.
- *
- * Note on locking:
- *      All callers to this class must <strong>lock on the class object they are calling</strong>.
- *      This is important b/c {@link com.android.server.task.TaskStore.WriteTasksMapToDiskRunnable}
- *      and {@link com.android.server.task.TaskStore.ReadTaskMapFromDiskRunnable} lock on that
- *      object.
- */
-public class TaskStore {
-    private static final String TAG = "TaskManagerStore";
-    private static final boolean DEBUG = TaskManagerService.DEBUG;
-
-    /** Threshold to adjust how often we want to write to the db. */
-    private static final int MAX_OPS_BEFORE_WRITE = 1;
-    final ArraySet<TaskStatus> mTasksSet;
-    final Context mContext;
-
-    private int mDirtyOperations;
-
-    private static final Object sSingletonLock = new Object();
-    private final AtomicFile mTasksFile;
-    /** Handler backed by IoThread for writing to disk. */
-    private final Handler mIoHandler = IoThread.getHandler();
-    private static TaskStore sSingleton;
-
-    /** Used by the {@Link TaskManagerService} to instantiate the TaskStore. */
-    static TaskStore initAndGet(TaskManagerService taskManagerService) {
-        synchronized (sSingletonLock) {
-            if (sSingleton == null) {
-                sSingleton = new TaskStore(taskManagerService.getContext(),
-                        Environment.getDataDirectory(), taskManagerService);
-            }
-            return sSingleton;
-        }
-    }
-
-    @VisibleForTesting
-    public static TaskStore initAndGetForTesting(Context context, File dataDir,
-                                                 TaskMapReadFinishedListener callback) {
-        return new TaskStore(context, dataDir, callback);
-    }
-
-    private TaskStore(Context context, File dataDir, TaskMapReadFinishedListener callback) {
-        mContext = context;
-        mDirtyOperations = 0;
-
-        File systemDir = new File(dataDir, "system");
-        File taskDir = new File(systemDir, "task");
-        taskDir.mkdirs();
-        mTasksFile = new AtomicFile(new File(taskDir, "tasks.xml"));
-
-        mTasksSet = new ArraySet<TaskStatus>();
-
-        readTaskMapFromDiskAsync(callback);
-    }
-
-    /**
-     * Add a task to the master list, persisting it if necessary. If the TaskStatus already exists,
-     * it will be replaced.
-     * @param taskStatus Task to add.
-     * @return Whether or not an equivalent TaskStatus was replaced by this operation.
-     */
-    public boolean add(TaskStatus taskStatus) {
-        boolean replaced = mTasksSet.remove(taskStatus);
-        mTasksSet.add(taskStatus);
-        if (taskStatus.isPersisted()) {
-            maybeWriteStatusToDiskAsync();
-        }
-        if (DEBUG) {
-            Slog.d(TAG, "Added task status to store: " + taskStatus);
-        }
-        return replaced;
-    }
-
-    /**
-     * Whether this taskStatus object already exists in the TaskStore.
-     */
-    public boolean containsTaskIdForUid(int taskId, int uId) {
-        for (TaskStatus ts : mTasksSet) {
-            if (ts.getUid() == uId && ts.getTaskId() == taskId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public int size() {
-        return mTasksSet.size();
-    }
-
-    /**
-     * Remove the provided task. Will also delete the task if it was persisted.
-     * @return Whether or not the task existed to be removed.
-     */
-    public boolean remove(TaskStatus taskStatus) {
-        boolean removed = mTasksSet.remove(taskStatus);
-        if (!removed) {
-            if (DEBUG) {
-                Slog.d(TAG, "Couldn't remove task: didn't exist: " + taskStatus);
-            }
-            return false;
-        }
-        maybeWriteStatusToDiskAsync();
-        return removed;
-    }
-
-    @VisibleForTesting
-    public void clear() {
-        mTasksSet.clear();
-        maybeWriteStatusToDiskAsync();
-    }
-
-    public List<TaskStatus> getTasksByUser(int userHandle) {
-        List<TaskStatus> matchingTasks = new ArrayList<TaskStatus>();
-        Iterator<TaskStatus> it = mTasksSet.iterator();
-        while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (UserHandle.getUserId(ts.getUid()) == userHandle) {
-                matchingTasks.add(ts);
-            }
-        }
-        return matchingTasks;
-    }
-
-    /**
-     * @param uid Uid of the requesting app.
-     * @return All TaskStatus objects for a given uid from the master list.
-     */
-    public List<TaskStatus> getTasksByUid(int uid) {
-        List<TaskStatus> matchingTasks = new ArrayList<TaskStatus>();
-        Iterator<TaskStatus> it = mTasksSet.iterator();
-        while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (ts.getUid() == uid) {
-                matchingTasks.add(ts);
-            }
-        }
-        return matchingTasks;
-    }
-
-    /**
-     * @param uid Uid of the requesting app.
-     * @param taskId Task id, specified at schedule-time.
-     * @return the TaskStatus that matches the provided uId and taskId, or null if none found.
-     */
-    public TaskStatus getTaskByUidAndTaskId(int uid, int taskId) {
-        Iterator<TaskStatus> it = mTasksSet.iterator();
-        while (it.hasNext()) {
-            TaskStatus ts = it.next();
-            if (ts.getUid() == uid && ts.getTaskId() == taskId) {
-                return ts;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @return The live array of TaskStatus objects.
-     */
-    public ArraySet<TaskStatus> getTasks() {
-        return mTasksSet;
-    }
-
-    /** Version of the db schema. */
-    private static final int TASKS_FILE_VERSION = 0;
-    /** Tag corresponds to constraints this task needs. */
-    private static final String XML_TAG_PARAMS_CONSTRAINTS = "constraints";
-    /** Tag corresponds to execution parameters. */
-    private static final String XML_TAG_PERIODIC = "periodic";
-    private static final String XML_TAG_ONEOFF = "one-off";
-    private static final String XML_TAG_EXTRAS = "extras";
-
-    /**
-     * Every time the state changes we write all the tasks in one swathe, instead of trying to
-     * track incremental changes.
-     * @return Whether the operation was successful. This will only fail for e.g. if the system is
-     * low on storage. If this happens, we continue as normal
-     */
-    private void maybeWriteStatusToDiskAsync() {
-        mDirtyOperations++;
-        if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) {
-            if (DEBUG) {
-                Slog.v(TAG, "Writing tasks to disk.");
-            }
-            mIoHandler.post(new WriteTasksMapToDiskRunnable());
-        }
-    }
-
-    private void readTaskMapFromDiskAsync(TaskMapReadFinishedListener callback) {
-        mIoHandler.post(new ReadTaskMapFromDiskRunnable(callback));
-    }
-
-    public void readTaskMapFromDisk(TaskMapReadFinishedListener callback) {
-        new ReadTaskMapFromDiskRunnable(callback).run();
-    }
-
-    /**
-     * Runnable that writes {@link #mTasksSet} out to xml.
-     * NOTE: This Runnable locks on TaskStore.this
-     */
-    private class WriteTasksMapToDiskRunnable implements Runnable {
-        @Override
-        public void run() {
-            final long startElapsed = SystemClock.elapsedRealtime();
-            synchronized (TaskStore.this) {
-                writeTasksMapImpl();
-            }
-            if (TaskManagerService.DEBUG) {
-                Slog.v(TAG, "Finished writing, took " + (SystemClock.elapsedRealtime()
-                        - startElapsed) + "ms");
-            }
-        }
-
-        private void writeTasksMapImpl() {
-            try {
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(baos, "utf-8");
-                out.startDocument(null, true);
-                out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
-                out.startTag(null, "task-info");
-                out.attribute(null, "version", Integer.toString(TASKS_FILE_VERSION));
-                for (int i = 0; i < mTasksSet.size(); i++) {
-                    final TaskStatus taskStatus = mTasksSet.valueAt(i);
-                    if (DEBUG) {
-                        Slog.d(TAG, "Saving task " + taskStatus.getTaskId());
-                    }
-                    out.startTag(null, "task");
-                    addIdentifierAttributesToTaskTag(out, taskStatus);
-                    writeConstraintsToXml(out, taskStatus);
-                    writeExecutionCriteriaToXml(out, taskStatus);
-                    writeBundleToXml(taskStatus.getExtras(), out);
-                    out.endTag(null, "task");
-                }
-                out.endTag(null, "task-info");
-                out.endDocument();
-
-                // Write out to disk in one fell sweep.
-                FileOutputStream fos = mTasksFile.startWrite();
-                fos.write(baos.toByteArray());
-                mTasksFile.finishWrite(fos);
-                mDirtyOperations = 0;
-            } catch (IOException e) {
-                if (DEBUG) {
-                    Slog.v(TAG, "Error writing out task data.", e);
-                }
-            } catch (XmlPullParserException e) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Error persisting bundle.", e);
-                }
-            }
-        }
-
-        /** Write out a tag with data comprising the required fields of this task and its client. */
-        private void addIdentifierAttributesToTaskTag(XmlSerializer out, TaskStatus taskStatus)
-                throws IOException {
-            out.attribute(null, "taskid", Integer.toString(taskStatus.getTaskId()));
-            out.attribute(null, "package", taskStatus.getServiceComponent().getPackageName());
-            out.attribute(null, "class", taskStatus.getServiceComponent().getClassName());
-            out.attribute(null, "uid", Integer.toString(taskStatus.getUid()));
-        }
-
-        private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
-                throws IOException, XmlPullParserException {
-            out.startTag(null, XML_TAG_EXTRAS);
-            extras.saveToXml(out);
-            out.endTag(null, XML_TAG_EXTRAS);
-        }
-        /**
-         * Write out a tag with data identifying this tasks constraints. If the constraint isn't here
-         * it doesn't apply.
-         */
-        private void writeConstraintsToXml(XmlSerializer out, TaskStatus taskStatus) throws IOException {
-            out.startTag(null, XML_TAG_PARAMS_CONSTRAINTS);
-            if (taskStatus.hasUnmeteredConstraint()) {
-                out.attribute(null, "unmetered", Boolean.toString(true));
-            }
-            if (taskStatus.hasConnectivityConstraint()) {
-                out.attribute(null, "connectivity", Boolean.toString(true));
-            }
-            if (taskStatus.hasIdleConstraint()) {
-                out.attribute(null, "idle", Boolean.toString(true));
-            }
-            if (taskStatus.hasChargingConstraint()) {
-                out.attribute(null, "charging", Boolean.toString(true));
-            }
-            out.endTag(null, XML_TAG_PARAMS_CONSTRAINTS);
-        }
-
-        private void writeExecutionCriteriaToXml(XmlSerializer out, TaskStatus taskStatus)
-                throws IOException {
-            final Task task = taskStatus.getTask();
-            if (taskStatus.getTask().isPeriodic()) {
-                out.startTag(null, XML_TAG_PERIODIC);
-                out.attribute(null, "period", Long.toString(task.getIntervalMillis()));
-            } else {
-                out.startTag(null, XML_TAG_ONEOFF);
-            }
-
-            if (taskStatus.hasDeadlineConstraint()) {
-                // Wall clock deadline.
-                final long deadlineWallclock =  System.currentTimeMillis() +
-                        (taskStatus.getLatestRunTimeElapsed() - SystemClock.elapsedRealtime());
-                out.attribute(null, "deadline", Long.toString(deadlineWallclock));
-            }
-            if (taskStatus.hasTimingDelayConstraint()) {
-                final long delayWallclock = System.currentTimeMillis() +
-                        (taskStatus.getEarliestRunTime() - SystemClock.elapsedRealtime());
-                out.attribute(null, "delay", Long.toString(delayWallclock));
-            }
-
-            // Only write out back-off policy if it differs from the default.
-            // This also helps the case where the task is idle -> these aren't allowed to specify
-            // back-off.
-            if (taskStatus.getTask().getInitialBackoffMillis() != Task.DEFAULT_INITIAL_BACKOFF_MILLIS
-                    || taskStatus.getTask().getBackoffPolicy() != Task.DEFAULT_BACKOFF_POLICY) {
-                out.attribute(null, "backoff-policy", Integer.toString(task.getBackoffPolicy()));
-                out.attribute(null, "initial-backoff", Long.toString(task.getInitialBackoffMillis()));
-            }
-            if (task.isPeriodic()) {
-                out.endTag(null, XML_TAG_PERIODIC);
-            } else {
-                out.endTag(null, XML_TAG_ONEOFF);
-            }
-        }
-    }
-
-    /**
-     * Runnable that reads list of persisted task from xml.
-     * NOTE: This Runnable locks on TaskStore.this
-     */
-    private class ReadTaskMapFromDiskRunnable implements Runnable {
-        private TaskMapReadFinishedListener mCallback;
-        public ReadTaskMapFromDiskRunnable(TaskMapReadFinishedListener callback) {
-            mCallback = callback;
-        }
-
-        @Override
-        public void run() {
-            try {
-                List<TaskStatus> tasks;
-                FileInputStream fis = mTasksFile.openRead();
-                synchronized (TaskStore.this) {
-                    tasks = readTaskMapImpl(fis);
-                }
-                fis.close();
-                if (tasks != null) {
-                    mCallback.onTaskMapReadFinished(tasks);
-                }
-            } catch (FileNotFoundException e) {
-                if (TaskManagerService.DEBUG) {
-                    Slog.d(TAG, "Could not find tasks file, probably there was nothing to load.");
-                }
-            } catch (XmlPullParserException e) {
-                if (TaskManagerService.DEBUG) {
-                    Slog.d(TAG, "Error parsing xml.", e);
-                }
-            } catch (IOException e) {
-                if (TaskManagerService.DEBUG) {
-                    Slog.d(TAG, "Error parsing xml.", e);
-                }
-            }
-        }
-
-        private List<TaskStatus> readTaskMapImpl(FileInputStream fis) throws XmlPullParserException, IOException {
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(fis, null);
-
-            int eventType = parser.getEventType();
-            while (eventType != XmlPullParser.START_TAG &&
-                    eventType != XmlPullParser.END_DOCUMENT) {
-                eventType = parser.next();
-                Slog.d(TAG, parser.getName());
-            }
-            if (eventType == XmlPullParser.END_DOCUMENT) {
-                if (DEBUG) {
-                    Slog.d(TAG, "No persisted tasks.");
-                }
-                return null;
-            }
-
-            String tagName = parser.getName();
-            if ("task-info".equals(tagName)) {
-                final List<TaskStatus> tasks = new ArrayList<TaskStatus>();
-                // Read in version info.
-                try {
-                    int version = Integer.valueOf(parser.getAttributeValue(null, "version"));
-                    if (version != TASKS_FILE_VERSION) {
-                        Slog.d(TAG, "Invalid version number, aborting tasks file read.");
-                        return null;
-                    }
-                } catch (NumberFormatException e) {
-                    Slog.e(TAG, "Invalid version number, aborting tasks file read.");
-                    return null;
-                }
-                eventType = parser.next();
-                do {
-                    // Read each <task/>
-                    if (eventType == XmlPullParser.START_TAG) {
-                        tagName = parser.getName();
-                        // Start reading task.
-                        if ("task".equals(tagName)) {
-                            TaskStatus persistedTask = restoreTaskFromXml(parser);
-                            if (persistedTask != null) {
-                                if (DEBUG) {
-                                    Slog.d(TAG, "Read out " + persistedTask);
-                                }
-                                tasks.add(persistedTask);
-                            } else {
-                                Slog.d(TAG, "Error reading task from file.");
-                            }
-                        }
-                    }
-                    eventType = parser.next();
-                } while (eventType != XmlPullParser.END_DOCUMENT);
-                return tasks;
-            }
-            return null;
-        }
-
-        /**
-         * @param parser Xml parser at the beginning of a "<task/>" tag. The next "parser.next()" call
-         *               will take the parser into the body of the task tag.
-         * @return Newly instantiated task holding all the information we just read out of the xml tag.
-         */
-        private TaskStatus restoreTaskFromXml(XmlPullParser parser) throws XmlPullParserException,
-                IOException {
-            Task.Builder taskBuilder;
-            int uid;
-
-            // Read out task identifier attributes.
-            try {
-                taskBuilder = buildBuilderFromXml(parser);
-                uid = Integer.valueOf(parser.getAttributeValue(null, "uid"));
-            } catch (NumberFormatException e) {
-                Slog.e(TAG, "Error parsing task's required fields, skipping");
-                return null;
-            }
-
-            int eventType;
-            // Read out constraints tag.
-            do {
-                eventType = parser.next();
-            } while (eventType == XmlPullParser.TEXT);  // Push through to next START_TAG.
-
-            if (!(eventType == XmlPullParser.START_TAG &&
-                    XML_TAG_PARAMS_CONSTRAINTS.equals(parser.getName()))) {
-                // Expecting a <constraints> start tag.
-                return null;
-            }
-            try {
-                buildConstraintsFromXml(taskBuilder, parser);
-            } catch (NumberFormatException e) {
-                Slog.d(TAG, "Error reading constraints, skipping.");
-                return null;
-            }
-            parser.next(); // Consume </constraints>
-
-            // Read out execution parameters tag.
-            do {
-                eventType = parser.next();
-            } while (eventType == XmlPullParser.TEXT);
-            if (eventType != XmlPullParser.START_TAG) {
-                return null;
-            }
-
-            Pair<Long, Long> runtimes;
-            try {
-                runtimes = buildExecutionTimesFromXml(parser);
-            } catch (NumberFormatException e) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Error parsing execution time parameters, skipping.");
-                }
-                return null;
-            }
-
-            if (XML_TAG_PERIODIC.equals(parser.getName())) {
-                try {
-                    String val = parser.getAttributeValue(null, "period");
-                    taskBuilder.setPeriodic(Long.valueOf(val));
-                } catch (NumberFormatException e) {
-                    Slog.d(TAG, "Error reading periodic execution criteria, skipping.");
-                    return null;
-                }
-            } else if (XML_TAG_ONEOFF.equals(parser.getName())) {
-                try {
-                    if (runtimes.first != TaskStatus.NO_EARLIEST_RUNTIME) {
-                        taskBuilder.setMinimumLatency(runtimes.first - SystemClock.elapsedRealtime());
-                    }
-                    if (runtimes.second != TaskStatus.NO_LATEST_RUNTIME) {
-                        taskBuilder.setOverrideDeadline(
-                                runtimes.second - SystemClock.elapsedRealtime());
-                    }
-                } catch (NumberFormatException e) {
-                    Slog.d(TAG, "Error reading task execution criteria, skipping.");
-                    return null;
-                }
-            } else {
-                if (DEBUG) {
-                    Slog.d(TAG, "Invalid parameter tag, skipping - " + parser.getName());
-                }
-                // Expecting a parameters start tag.
-                return null;
-            }
-            maybeBuildBackoffPolicyFromXml(taskBuilder, parser);
-
-            parser.nextTag(); // Consume parameters end tag.
-
-            // Read out extras Bundle.
-            do {
-                eventType = parser.next();
-            } while (eventType == XmlPullParser.TEXT);
-            if (!(eventType == XmlPullParser.START_TAG && XML_TAG_EXTRAS.equals(parser.getName()))) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Error reading extras, skipping.");
-                }
-                return null;
-            }
-
-            PersistableBundle extras = PersistableBundle.restoreFromXml(parser);
-            taskBuilder.setExtras(extras);
-            parser.nextTag(); // Consume </extras>
-
-            return new TaskStatus(taskBuilder.build(), uid, runtimes.first, runtimes.second);
-        }
-
-        private Task.Builder buildBuilderFromXml(XmlPullParser parser) throws NumberFormatException {
-            // Pull out required fields from <task> attributes.
-            int taskId = Integer.valueOf(parser.getAttributeValue(null, "taskid"));
-            String packageName = parser.getAttributeValue(null, "package");
-            String className = parser.getAttributeValue(null, "class");
-            ComponentName cname = new ComponentName(packageName, className);
-
-            return new Task.Builder(taskId, cname);
-        }
-
-        private void buildConstraintsFromXml(Task.Builder taskBuilder, XmlPullParser parser) {
-            String val = parser.getAttributeValue(null, "unmetered");
-            if (val != null) {
-                taskBuilder.setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED);
-            }
-            val = parser.getAttributeValue(null, "connectivity");
-            if (val != null) {
-                taskBuilder.setRequiredNetworkCapabilities(Task.NetworkType.ANY);
-            }
-            val = parser.getAttributeValue(null, "idle");
-            if (val != null) {
-                taskBuilder.setRequiresDeviceIdle(true);
-            }
-            val = parser.getAttributeValue(null, "charging");
-            if (val != null) {
-                taskBuilder.setRequiresCharging(true);
-            }
-        }
-
-        /**
-         * Builds the back-off policy out of the params tag. These attributes may not exist, depending
-         * on whether the back-off was set when the task was first scheduled.
-         */
-        private void maybeBuildBackoffPolicyFromXml(Task.Builder taskBuilder, XmlPullParser parser) {
-            String val = parser.getAttributeValue(null, "initial-backoff");
-            if (val != null) {
-                long initialBackoff = Long.valueOf(val);
-                val = parser.getAttributeValue(null, "backoff-policy");
-                int backoffPolicy = Integer.valueOf(val);  // Will throw NFE which we catch higher up.
-                taskBuilder.setBackoffCriteria(initialBackoff, backoffPolicy);
-            }
-        }
-
-        /**
-         * Convenience function to read out and convert deadline and delay from xml into elapsed real
-         * time.
-         * @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime
-         * and the second is the latest elapsed runtime.
-         */
-        private Pair<Long, Long> buildExecutionTimesFromXml(XmlPullParser parser)
-                throws NumberFormatException {
-            // Pull out execution time data.
-            final long nowWallclock = System.currentTimeMillis();
-            final long nowElapsed = SystemClock.elapsedRealtime();
-
-            long earliestRunTimeElapsed = TaskStatus.NO_EARLIEST_RUNTIME;
-            long latestRunTimeElapsed = TaskStatus.NO_LATEST_RUNTIME;
-            String val = parser.getAttributeValue(null, "deadline");
-            if (val != null) {
-                long latestRuntimeWallclock = Long.valueOf(val);
-                long maxDelayElapsed =
-                        Math.max(latestRuntimeWallclock - nowWallclock, 0);
-                latestRunTimeElapsed = nowElapsed + maxDelayElapsed;
-            }
-            val = parser.getAttributeValue(null, "delay");
-            if (val != null) {
-                long earliestRuntimeWallclock = Long.valueOf(val);
-                long minDelayElapsed =
-                        Math.max(earliestRuntimeWallclock - nowWallclock, 0);
-                earliestRunTimeElapsed = nowElapsed + minDelayElapsed;
-
-            }
-            return Pair.create(earliestRunTimeElapsed, latestRunTimeElapsed);
-        }
-    }
-}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/task/controllers/TaskStatus.java b/services/core/java/com/android/server/task/controllers/TaskStatus.java
deleted file mode 100644
index a286737..0000000
--- a/services/core/java/com/android/server/task/controllers/TaskStatus.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task.controllers;
-
-import android.app.task.Task;
-import android.content.ComponentName;
-import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.os.UserHandle;
-
-import java.io.PrintWriter;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Uniquely identifies a task internally.
- * Created from the public {@link android.app.task.Task} object when it lands on the scheduler.
- * Contains current state of the requirements of the task, as well as a function to evaluate
- * whether it's ready to run.
- * This object is shared among the various controllers - hence why the different fields are atomic.
- * This isn't strictly necessary because each controller is only interested in a specific field,
- * and the receivers that are listening for global state change will all run on the main looper,
- * but we don't enforce that so this is safer.
- * @hide
- */
-public class TaskStatus {
-    public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
-    public static final long NO_EARLIEST_RUNTIME = 0L;
-
-    final Task task;
-    final int uId;
-
-    /** At reschedule time we need to know whether to update task on disk. */
-    final boolean persisted;
-
-    // Constraints.
-    final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean deadlineConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean idleConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean unmeteredConstraintSatisfied = new AtomicBoolean();
-    final AtomicBoolean connectivityConstraintSatisfied = new AtomicBoolean();
-
-    /**
-     * Earliest point in the future at which this task will be eligible to run. A value of 0
-     * indicates there is no delay constraint. See {@link #hasTimingDelayConstraint()}.
-     */
-    private long earliestRunTimeElapsedMillis;
-    /**
-     * Latest point in the future at which this task must be run. A value of {@link Long#MAX_VALUE}
-     * indicates there is no deadline constraint. See {@link #hasDeadlineConstraint()}.
-     */
-    private long latestRunTimeElapsedMillis;
-    /** How many times this task has failed, used to compute back-off. */
-    private final int numFailures;
-
-    /** Provide a handle to the service that this task will be run on. */
-    public int getServiceToken() {
-        return uId;
-    }
-
-    private TaskStatus(Task task, int uId, boolean persisted, int numFailures) {
-        this.task = task;
-        this.uId = uId;
-        this.numFailures = numFailures;
-        this.persisted = persisted;
-    }
-
-    /** Create a newly scheduled task. */
-    public TaskStatus(Task task, int uId, boolean persisted) {
-        this(task, uId, persisted, 0);
-
-        final long elapsedNow = SystemClock.elapsedRealtime();
-
-        if (task.isPeriodic()) {
-            earliestRunTimeElapsedMillis = elapsedNow;
-            latestRunTimeElapsedMillis = elapsedNow + task.getIntervalMillis();
-        } else {
-            earliestRunTimeElapsedMillis = task.hasEarlyConstraint() ?
-                    elapsedNow + task.getMinLatencyMillis() : NO_EARLIEST_RUNTIME;
-            latestRunTimeElapsedMillis = task.hasLateConstraint() ?
-                    elapsedNow + task.getMaxExecutionDelayMillis() : NO_LATEST_RUNTIME;
-        }
-    }
-
-    /**
-     * Create a new TaskStatus that was loaded from disk. We ignore the provided
-     * {@link android.app.task.Task} time criteria because we can load a persisted periodic task
-     * from the {@link com.android.server.task.TaskStore} and still want to respect its
-     * wallclock runtime rather than resetting it on every boot.
-     * We consider a freshly loaded task to no longer be in back-off.
-     */
-    public TaskStatus(Task task, int uId, long earliestRunTimeElapsedMillis,
-                      long latestRunTimeElapsedMillis) {
-        this(task, uId, true, 0);
-
-        this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
-        this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
-    }
-
-    /** Create a new task to be rescheduled with the provided parameters. */
-    public TaskStatus(TaskStatus rescheduling, long newEarliestRuntimeElapsedMillis,
-                      long newLatestRuntimeElapsedMillis, int backoffAttempt) {
-        this(rescheduling.task, rescheduling.getUid(), rescheduling.isPersisted(), backoffAttempt);
-
-        earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
-        latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
-    }
-
-    public Task getTask() {
-        return task;
-    }
-
-    public int getTaskId() {
-        return task.getId();
-    }
-
-    public int getNumFailures() {
-        return numFailures;
-    }
-
-    public ComponentName getServiceComponent() {
-        return task.getService();
-    }
-
-    public int getUserId() {
-        return UserHandle.getUserId(uId);
-    }
-
-    public int getUid() {
-        return uId;
-    }
-
-    public PersistableBundle getExtras() {
-        return task.getExtras();
-    }
-
-    public boolean hasConnectivityConstraint() {
-        return task.getNetworkCapabilities() == Task.NetworkType.ANY;
-    }
-
-    public boolean hasUnmeteredConstraint() {
-        return task.getNetworkCapabilities() == Task.NetworkType.UNMETERED;
-    }
-
-    public boolean hasChargingConstraint() {
-        return task.isRequireCharging();
-    }
-
-    public boolean hasTimingDelayConstraint() {
-        return earliestRunTimeElapsedMillis != NO_EARLIEST_RUNTIME;
-    }
-
-    public boolean hasDeadlineConstraint() {
-        return latestRunTimeElapsedMillis != NO_LATEST_RUNTIME;
-    }
-
-    public boolean hasIdleConstraint() {
-        return task.isRequireDeviceIdle();
-    }
-
-    public long getEarliestRunTime() {
-        return earliestRunTimeElapsedMillis;
-    }
-
-    public long getLatestRunTimeElapsed() {
-        return latestRunTimeElapsedMillis;
-    }
-
-    public boolean isPersisted() {
-        return persisted;
-    }
-    /**
-     * @return Whether or not this task is ready to run, based on its requirements.
-     */
-    public synchronized boolean isReady() {
-        return (!hasChargingConstraint() || chargingConstraintSatisfied.get())
-                && (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
-                && (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
-                && (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
-                && (!hasIdleConstraint() || idleConstraintSatisfied.get())
-                // Also ready if the deadline has expired - special case.
-                || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
-    }
-
-    /*@Override
-    public int hashCode() {
-        int result = getServiceComponent().hashCode();
-        result = 31 * result + task.getId();
-        result = 31 * result + uId;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof TaskStatus)) return false;
-
-        TaskStatus that = (TaskStatus) o;
-        return ((task.getId() == that.task.getId())
-                && (uId == that.uId)
-                && (getServiceComponent().equals(that.getServiceComponent())));
-    }*/
-
-    public boolean matches(int uid, int taskId) {
-        return this.task.getId() == taskId && this.uId == uid;
-    }
-
-    @Override
-    public String toString() {
-        return String.valueOf(hashCode()).substring(0, 3) + ".."
-                + ":[" + task.getService().getPackageName() + ",tId=" + task.getId()
-                + ",R=(" + earliestRunTimeElapsedMillis + "," + latestRunTimeElapsedMillis + ")"
-                + ",N=" + task.getNetworkCapabilities() + ",C=" + task.isRequireCharging()
-                + ",I=" + task.isRequireDeviceIdle() + ",F=" + numFailures
-                + (isReady() ? "(READY)" : "")
-                + "]";
-    }
-    // Dumpsys infrastructure
-    public void dump(PrintWriter pw, String prefix) {
-        pw.println(this.toString());
-    }
-}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 10a67c4..7a95823 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -102,11 +102,9 @@
         mLogHandler = new LogHandler(IoThread.get().getLooper());
 
         mTvInputHardwareManager = new TvInputHardwareManager(context);
-        registerBroadcastReceivers();
 
         synchronized (mLock) {
             mUserStates.put(mCurrentUserId, new UserState());
-            buildTvInputListLocked(mCurrentUserId);
         }
     }
 
@@ -115,6 +113,16 @@
         publishBinderService(Context.TV_INPUT_SERVICE, new BinderService());
     }
 
+    @Override
+    public void onBootPhase(int phase) {
+        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+            registerBroadcastReceivers();
+            synchronized (mLock) {
+                buildTvInputListLocked(mCurrentUserId);
+            }
+        }
+    }
+
     private void registerBroadcastReceivers() {
         PackageMonitor monitor = new PackageMonitor() {
             @Override
@@ -124,7 +132,7 @@
                 }
             }
         };
-        monitor.register(mContext, null, UserHandle.ALL, true);
+        monitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, true);
 
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2aa1220..54be537 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -65,6 +65,7 @@
 import com.android.server.dreams.DreamManagerService;
 import com.android.server.hdmi.HdmiControlService;
 import com.android.server.input.InputManagerService;
+import com.android.server.job.JobSchedulerService;
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LightsService;
 import com.android.server.media.MediaRouterService;
@@ -83,7 +84,6 @@
 import com.android.server.search.SearchManagerService;
 import com.android.server.statusbar.StatusBarManagerService;
 import com.android.server.storage.DeviceStorageMonitorService;
-import com.android.server.task.TaskManagerService;
 import com.android.server.trust.TrustManagerService;
 import com.android.server.tv.TvInputManagerService;
 import com.android.server.twilight.TwilightService;
@@ -131,8 +131,8 @@
             "com.android.server.wifi.p2p.WifiP2pService";
     private static final String ETHERNET_SERVICE_CLASS =
             "com.android.server.ethernet.EthernetService";
-    private static final String TASK_SERVICE_CLASS =
-            "com.android.server.task.TaskManagerService";
+    private static final String JOB_SCHEDULER_SERVICE_CLASS =
+            "com.android.server.job.JobSchedulerService";
 
     private final int mFactoryTestMode;
     private Timer mProfilerSnapshotTimer;
@@ -349,6 +349,7 @@
         boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
         boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
         boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
+        boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
 
         try {
             Slog.i(TAG, "Telephony Registry");
@@ -461,7 +462,7 @@
             // Skip Bluetooth if we have an emulator kernel
             // TODO: Use a more reliable check to see if this product should
             // support Bluetooth - see bug 988521
-            if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
+            if (isEmulator) {
                 Slog.i(TAG, "No Bluetooh Service (emulator)");
             } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                 Slog.i(TAG, "No Bluetooth Service (factory test)");
@@ -662,10 +663,17 @@
                     reportWtf("starting Wi-Fi Scanning Service", e);
                 }
 
-                try {
-                    mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
-                } catch (Throwable e) {
-                    reportWtf("starting Ethernet Service", e);
+                if (!isEmulator) {
+                    try {
+                        mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
+                    } catch (Throwable e) {
+                        reportWtf("starting Ethernet Service", e);
+                    }
+                } else {
+                    // Don't start the Ethernet service on the emulator because
+                    // it interferes with qemu's SLIRP emulation, which uses
+                    // IPv4 over eth0. http://b/15341003 .
+                    Slog.i(TAG, "Not starting Ethernet service (emulator)");
                 }
 
                 try {
@@ -832,7 +840,7 @@
 
             mSystemServiceManager.startService(UiModeManagerService.class);
 
-            mSystemServiceManager.startService(TaskManagerService.class);
+            mSystemServiceManager.startService(JobSchedulerService.class);
 
             if (!disableNonCoreServices) {
                 try {
diff --git a/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java b/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
index e7f9ca0..7a7fa07 100644
--- a/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/task/TaskStoreTest.java
@@ -3,18 +3,19 @@
 
 import android.content.ComponentName;
 import android.content.Context;
-import android.app.task.Task;
-import android.app.task.Task.Builder;
+import android.app.job.JobInfo;
+import android.app.job.JobInfo.Builder;
 import android.os.PersistableBundle;
 import android.test.AndroidTestCase;
 import android.test.RenamingDelegatingContext;
 import android.util.Log;
 
-import com.android.server.task.controllers.TaskStatus;
+import com.android.server.job.JobMapReadFinishedListener;
+import com.android.server.job.JobStore;
+import com.android.server.job.controllers.JobStatus;
 
 import java.util.List;
 
-import static com.android.server.task.TaskStore.initAndGet;
 /**
  * Test reading and writing correctly from file.
  */
@@ -26,12 +27,12 @@
     private ComponentName mComponent;
     private static final long IO_WAIT = 600L;
 
-    TaskStore mTaskStoreUnderTest;
+    JobStore mTaskStoreUnderTest;
     Context mTestContext;
-    TaskMapReadFinishedListener mTaskMapReadFinishedListenerStub =
-            new TaskMapReadFinishedListener() {
+    JobMapReadFinishedListener mTaskMapReadFinishedListenerStub =
+            new JobMapReadFinishedListener() {
         @Override
-        public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+        public void onJobMapReadFinished(List<JobStatus> tasks) {
             // do nothing.
         }
     };
@@ -40,7 +41,7 @@
     public void setUp() throws Exception {
         mTestContext = new RenamingDelegatingContext(getContext(), TEST_PREFIX);
         Log.d(TAG, "Saving tasks to '" + mTestContext.getFilesDir() + "'");
-        mTaskStoreUnderTest = TaskStore.initAndGetForTesting(mTestContext,
+        mTaskStoreUnderTest = JobStore.initAndGetForTesting(mTestContext,
                 mTestContext.getFilesDir(), mTaskMapReadFinishedListenerStub);
         mComponent = new ComponentName(getContext().getPackageName(), StubClass.class.getName());
     }
@@ -56,23 +57,23 @@
         long runFromMillis = 2000L; // 2s
         long initialBackoff = 10000L; // 10s
 
-        final Task task = new Builder(taskId, mComponent)
+        final JobInfo task = new Builder(taskId, mComponent)
                 .setRequiresCharging(true)
-                .setRequiredNetworkCapabilities(Task.NetworkType.ANY)
-                .setBackoffCriteria(initialBackoff, Task.BackoffPolicy.EXPONENTIAL)
+                .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY)
+                .setBackoffCriteria(initialBackoff, JobInfo.BackoffPolicy.EXPONENTIAL)
                 .setOverrideDeadline(runByMillis)
                 .setMinimumLatency(runFromMillis)
                 .build();
-        final TaskStatus ts = new TaskStatus(task, SOME_UID, true /* persisted */);
+        final JobStatus ts = new JobStatus(task, SOME_UID, true /* persisted */);
         mTaskStoreUnderTest.add(ts);
         Thread.sleep(IO_WAIT);
         // Manually load tasks from xml file.
-        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+        mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() {
             @Override
-            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+            public void onJobMapReadFinished(List<JobStatus> tasks) {
                 assertEquals("Didn't get expected number of persisted tasks.", 1, tasks.size());
-                TaskStatus loadedTaskStatus = tasks.get(0);
-                assertTasksEqual(task, loadedTaskStatus.getTask());
+                JobStatus loadedTaskStatus = tasks.get(0);
+                assertTasksEqual(task, loadedTaskStatus.getJob());
                 assertEquals("Different uids.", SOME_UID, tasks.get(0).getUid());
                 compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
                         ts.getEarliestRunTime(), loadedTaskStatus.getEarliestRunTime());
@@ -84,30 +85,30 @@
     }
 
     public void testWritingTwoFilesToDisk() throws Exception {
-        final Task task1 = new Builder(8, mComponent)
+        final JobInfo task1 = new Builder(8, mComponent)
                 .setRequiresDeviceIdle(true)
                 .setPeriodic(10000L)
                 .setRequiresCharging(true)
                 .build();
-        final Task task2 = new Builder(12, mComponent)
+        final JobInfo task2 = new Builder(12, mComponent)
                 .setMinimumLatency(5000L)
-                .setBackoffCriteria(15000L, Task.BackoffPolicy.LINEAR)
+                .setBackoffCriteria(15000L, JobInfo.BackoffPolicy.LINEAR)
                 .setOverrideDeadline(30000L)
-                .setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED)
+                .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED)
                 .build();
-        final TaskStatus taskStatus1 = new TaskStatus(task1, SOME_UID, true /* persisted */);
-        final TaskStatus taskStatus2 = new TaskStatus(task2, SOME_UID, true /* persisted */);
+        final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID, true /* persisted */);
+        final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID, true /* persisted */);
         mTaskStoreUnderTest.add(taskStatus1);
         mTaskStoreUnderTest.add(taskStatus2);
         Thread.sleep(IO_WAIT);
-        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+        mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() {
             @Override
-            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+            public void onJobMapReadFinished(List<JobStatus> tasks) {
                 assertEquals("Incorrect # of persisted tasks.", 2, tasks.size());
-                TaskStatus loaded1 = tasks.get(0);
-                TaskStatus loaded2 = tasks.get(1);
-                assertTasksEqual(task1, loaded1.getTask());
-                assertTasksEqual(task2, loaded2.getTask());
+                JobStatus loaded1 = tasks.get(0);
+                JobStatus loaded2 = tasks.get(1);
+                assertTasksEqual(task1, loaded1.getJob());
+                assertTasksEqual(task2, loaded2.getJob());
 
                 // Check that the loaded task has the correct runtimes.
                 compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
@@ -124,7 +125,7 @@
     }
 
     public void testWritingTaskWithExtras() throws Exception {
-        Task.Builder b = new Builder(8, mComponent)
+        JobInfo.Builder b = new Builder(8, mComponent)
                 .setRequiresDeviceIdle(true)
                 .setPeriodic(10000L)
                 .setRequiresCharging(true);
@@ -134,17 +135,17 @@
         extras.putString("hi", "there");
         extras.putInt("into", 3);
         b.setExtras(extras);
-        final Task task = b.build();
-        TaskStatus taskStatus = new TaskStatus(task, SOME_UID, true /* persisted */);
+        final JobInfo task = b.build();
+        JobStatus taskStatus = new JobStatus(task, SOME_UID, true /* persisted */);
 
         mTaskStoreUnderTest.add(taskStatus);
         Thread.sleep(IO_WAIT);
-        mTaskStoreUnderTest.readTaskMapFromDisk(new TaskMapReadFinishedListener() {
+        mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() {
             @Override
-            public void onTaskMapReadFinished(List<TaskStatus> tasks) {
+            public void onJobMapReadFinished(List<JobStatus> tasks) {
                 assertEquals("Incorrect # of persisted tasks.", 1, tasks.size());
-                TaskStatus loaded = tasks.get(0);
-                assertTasksEqual(task, loaded.getTask());
+                JobStatus loaded = tasks.get(0);
+                assertTasksEqual(task, loaded.getJob());
             }
         });
 
@@ -153,7 +154,7 @@
     /**
      * Helper function to throw an error if the provided task and TaskStatus objects are not equal.
      */
-    private void assertTasksEqual(Task first, Task second) {
+    private void assertTasksEqual(JobInfo first, JobInfo second) {
         assertEquals("Different task ids.", first.getId(), second.getId());
         assertEquals("Different components.", first.getService(), second.getService());
         assertEquals("Different periodic status.", first.isPeriodic(), second.isPeriodic());
@@ -168,11 +169,11 @@
         assertEquals("Invalid idle constraint.", first.isRequireDeviceIdle(),
                 second.isRequireDeviceIdle());
         assertEquals("Invalid unmetered constraint.",
-                first.getNetworkCapabilities() == Task.NetworkType.UNMETERED,
-                second.getNetworkCapabilities() == Task.NetworkType.UNMETERED);
+                first.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED,
+                second.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED);
         assertEquals("Invalid connectivity constraint.",
-                first.getNetworkCapabilities() == Task.NetworkType.ANY,
-                second.getNetworkCapabilities() == Task.NetworkType.ANY);
+                first.getNetworkCapabilities() == JobInfo.NetworkType.ANY,
+                second.getNetworkCapabilities() == JobInfo.NetworkType.ANY);
         assertEquals("Invalid deadline constraint.",
                 first.hasLateConstraint(),
                 second.hasLateConstraint());
diff --git a/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java b/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java
deleted file mode 100644
index 6617a05..0000000
--- a/services/tests/servicestests/src/com/android/server/task/controllers/BatteryControllerTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.task.controllers;
-
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.test.AndroidTestCase;
-
-import com.android.server.task.StateChangedListener;
-
-import static com.android.server.task.controllers.BatteryController.getForTesting;
-
-import static org.mockito.Mockito.*;
-
-/**
- *
- */
-public class BatteryControllerTest extends AndroidTestCase {
-    BatteryController mBatteryControllerUnderTest;
-
-    StateChangedListener mStateChangedListenerStub = new StateChangedListener() {
-        @Override
-        public void onControllerStateChanged() {
-
-        }
-
-        @Override
-        public void onRunTaskNow(TaskStatus taskStatus) {
-
-        }
-    };
-    BatteryController.ChargingTracker mTrackerUnderTest;
-
-    public void setUp() throws Exception {
-        mBatteryControllerUnderTest = getForTesting(mStateChangedListenerStub, getTestContext());
-        mTrackerUnderTest = mBatteryControllerUnderTest.getTracker();
-    }
-
-    public void testSendBatteryChargingIntent() throws Exception {
-        Intent batteryConnectedIntent = new Intent(Intent.ACTION_POWER_CONNECTED)
-                .setComponent(new ComponentName(getContext(), mTrackerUnderTest.getClass()));
-        Intent batteryHealthyIntent = new Intent(Intent.ACTION_BATTERY_OKAY)
-                .setComponent(new ComponentName(getContext(), mTrackerUnderTest.getClass()));
-
-        mTrackerUnderTest.onReceiveInternal(batteryConnectedIntent);
-        mTrackerUnderTest.onReceiveInternal(batteryHealthyIntent);
-
-        assertTrue(mTrackerUnderTest.isOnStablePower());
-    }
-
-}
\ No newline at end of file
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 7aee770..164eeff 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -107,6 +107,13 @@
     protected Connection() {}
 
     /**
+     * The handle (e.g., phone number) to which this Connection is currently communicating.
+     *
+     * IMPORTANT: If an incoming connection has a phone number (or other handle) that the user
+     * is not supposed to be able to see (e.g. it is PRESENTATION_RESTRICTED), then a compliant
+     * ConnectionService implementation MUST NOT reveal this phone number and MUST return
+     * {@code null} from this method.
+     *
      * @return The handle (e.g., phone number) to which this Connection
      *         is currently communicating.
      */
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 9dfad2d..d974509 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -386,6 +386,11 @@
     /**
      * Create a Connection to match an incoming connection notification.
      *
+     * IMPORTANT: If the incoming connection has a phone number (or other handle) that the user
+     * is not supposed to be able to see (e.g. it is PRESENTATION_RESTRICTED), then a compliant
+     * ConnectionService implementation MUST NOT reveal this phone number as part of the Intent
+     * it sends to notify Telecomm of an incoming connection.
+     *
      * @param request Data encapsulating details of the desired Connection.
      * @param callback A callback for providing the result.
      */
diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java
index 86b7a50..ce52d19 100644
--- a/telecomm/java/android/telecomm/InCallAdapter.java
+++ b/telecomm/java/android/telecomm/InCallAdapter.java
@@ -59,10 +59,12 @@
      * is ported over.
      *
      * @param callId The identifier of the call to reject.
+     * @param rejectWithMessage Whether to reject with a text message.
+     * @param textMessage An optional text message with which to respond.
      */
-    public void rejectCall(String callId) {
+    public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
         try {
-            mAdapter.rejectCall(callId);
+            mAdapter.rejectCall(callId, rejectWithMessage, textMessage);
         } catch (RemoteException e) {
         }
     }
diff --git a/telecomm/java/android/telecomm/InCallCall.java b/telecomm/java/android/telecomm/InCallCall.java
index 432e378..66974f9 100644
--- a/telecomm/java/android/telecomm/InCallCall.java
+++ b/telecomm/java/android/telecomm/InCallCall.java
@@ -33,6 +33,7 @@
     private final CallState mState;
     private final int mDisconnectCauseCode;
     private final String mDisconnectCauseMsg;
+    private final List<String> mCannedSmsResponses;
     private final int mCapabilities;
     private final long mConnectTimeMillis;
     private final Uri mHandle;
@@ -49,14 +50,16 @@
             CallState state,
             int disconnectCauseCode,
             String disconnectCauseMsg,
+            List<String> cannedSmsResponses,
             int capabilities,
             long connectTimeMillis,
             Uri handle,
             GatewayInfo gatewayInfo,
             CallServiceDescriptor descriptor,
             CallServiceDescriptor handoffDescriptor) {
-        this(id, state, disconnectCauseCode, disconnectCauseMsg, capabilities, connectTimeMillis,
-                handle, gatewayInfo, descriptor, handoffDescriptor, null, Collections.EMPTY_LIST);
+        this(id, state, disconnectCauseCode, disconnectCauseMsg, cannedSmsResponses,
+                capabilities, connectTimeMillis, handle, gatewayInfo, descriptor, handoffDescriptor,
+                null, Collections.EMPTY_LIST);
     }
 
     /** @hide */
@@ -65,6 +68,7 @@
             CallState state,
             int disconnectCauseCode,
             String disconnectCauseMsg,
+            List<String> cannedSmsResponses,
             int capabilities,
             long connectTimeMillis,
             Uri handle,
@@ -77,6 +81,7 @@
         mState = state;
         mDisconnectCauseCode = disconnectCauseCode;
         mDisconnectCauseMsg = disconnectCauseMsg;
+        mCannedSmsResponses = cannedSmsResponses;
         mCapabilities = capabilities;
         mConnectTimeMillis = connectTimeMillis;
         mHandle = handle;
@@ -113,6 +118,13 @@
         return mDisconnectCauseMsg;
     }
 
+    /**
+     * The set of possible text message responses when this call is incoming.
+     */
+    public List<String> getCannedSmsResponses() {
+        return mCannedSmsResponses;
+    }
+
     // Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
     public int getCapabilities() {
         return mCapabilities;
@@ -168,13 +180,15 @@
             new Parcelable.Creator<InCallCall> () {
         @Override
         public InCallCall createFromParcel(Parcel source) {
+            ClassLoader classLoader = InCallCall.class.getClassLoader();
             String id = source.readString();
             CallState state = CallState.valueOf(source.readString());
             int disconnectCauseCode = source.readInt();
             String disconnectCauseMsg = source.readString();
+            List<String> cannedSmsResponses = new ArrayList<>();
+            source.readList(cannedSmsResponses, classLoader);
             int capabilities = source.readInt();
             long connectTimeMillis = source.readLong();
-            ClassLoader classLoader = InCallCall.class.getClassLoader();
             Uri handle = source.readParcelable(classLoader);
             GatewayInfo gatewayInfo = source.readParcelable(classLoader);
             CallServiceDescriptor descriptor = source.readParcelable(classLoader);
@@ -182,9 +196,9 @@
             String parentCallId = source.readString();
             List<String> childCallIds = new ArrayList<>();
             source.readList(childCallIds, classLoader);
-            return new InCallCall(id, state, disconnectCauseCode, disconnectCauseMsg, capabilities,
-                    connectTimeMillis, handle, gatewayInfo, descriptor, handoffDescriptor,
-                    parentCallId, childCallIds);
+            return new InCallCall(id, state, disconnectCauseCode, disconnectCauseMsg,
+                    cannedSmsResponses, capabilities, connectTimeMillis, handle, gatewayInfo,
+                    descriptor, handoffDescriptor, parentCallId, childCallIds);
         }
 
         @Override
@@ -206,6 +220,7 @@
         destination.writeString(mState.name());
         destination.writeInt(mDisconnectCauseCode);
         destination.writeString(mDisconnectCauseMsg);
+        destination.writeList(mCannedSmsResponses);
         destination.writeInt(mCapabilities);
         destination.writeLong(mConnectTimeMillis);
         destination.writeParcelable(mHandle, 0);
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
index 5717456..b66995a 100644
--- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
@@ -28,7 +28,7 @@
 oneway interface IInCallAdapter {
     void answerCall(String callId);
 
-    void rejectCall(String callId);
+    void rejectCall(String callId, boolean rejectWithMessage, String textMessage);
 
     void disconnectCall(String callId);
 
diff --git a/tests/JobSchedulerTestApp/AndroidManifest.xml b/tests/JobSchedulerTestApp/AndroidManifest.xml
index 7431737..9654197 100644
--- a/tests/JobSchedulerTestApp/AndroidManifest.xml
+++ b/tests/JobSchedulerTestApp/AndroidManifest.xml
@@ -25,6 +25,7 @@
 
         <service
             android:name=".service.TestJobService"
+            android:permission="android.permission.BIND_JOB_SERVICE"
             android:exported="true"/>
     </application>
 
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
index 393c594..15050ef 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
@@ -17,8 +17,8 @@
 package com.android.demo.jobSchedulerApp;
 
 import android.app.Activity;
-import android.app.task.Task;
-import android.app.task.TaskParams;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -80,10 +80,10 @@
     RadioButton mWiFiConnectivityRadioButton;
     RadioButton mAnyConnectivityRadioButton;
     ComponentName mServiceComponent;
-    /** Service object to interact scheduled tasks. */
+    /** Service object to interact scheduled jobs. */
     TestJobService mTestService;
 
-    private static int kTaskId = 0;
+    private static int kJobId = 0;
 
     Handler mHandler = new Handler(/* default looper */) {
         @Override
@@ -112,7 +112,7 @@
     }
 
     /**
-     * UI onclick listener to schedule a task. What this task is is defined in
+     * UI onclick listener to schedule a job. What this job is is defined in
      * TestJobService#scheduleJob()
      */
     public void scheduleJob(View v) {
@@ -120,7 +120,7 @@
             return;
         }
 
-        Task.Builder builder = new Task.Builder(kTaskId++, mServiceComponent);
+        JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);
 
         String delay = mDelayEditText.getText().toString();
         if (delay != null && !TextUtils.isEmpty(delay)) {
@@ -133,9 +133,9 @@
         boolean requiresUnmetered = mWiFiConnectivityRadioButton.isSelected();
         boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isSelected();
         if (requiresUnmetered) {
-            builder.setRequiredNetworkCapabilities(Task.NetworkType.UNMETERED);
+            builder.setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED);
         } else if (requiresAnyConnectivity) {
-            builder.setRequiredNetworkCapabilities(Task.NetworkType.ANY);
+            builder.setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY);
         }
 
         mTestService.scheduleJob(builder.build());
@@ -143,24 +143,24 @@
     }
 
     /**
-     * UI onclick listener to call taskFinished() in our service.
+     * UI onclick listener to call jobFinished() in our service.
      */
     public void finishJob(View v) {
         if (!ensureTestService()) {
             return;
         }
-        mTestService.callTaskFinished();
+        mTestService.callJobFinished();
         mParamsTextView.setText("");
     }
 
-    public void onReceivedStartTask(TaskParams params) {
+    public void onReceivedStartJob(JobParameters params) {
         mShowStartView.setBackgroundColor(startJobColor);
         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);
         mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.
-        mParamsTextView.setText("Executing: " + params.getTaskId() + " " + params.getExtras());
+        mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());
     }
 
-    public void onReceivedStopTask() {
+    public void onReceivedStopJob() {
         mShowStopView.setBackgroundColor(stopJobColor);
         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);
         mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
index 7dd3cf1..bf8e887 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
@@ -16,28 +16,20 @@
 
 package com.android.demo.jobSchedulerApp.service;
 
-import android.app.Service;
-import android.app.task.Task;
-import android.app.task.TaskManager;
-import android.app.task.TaskParams;
-import android.app.task.TaskService;
-import android.content.ComponentName;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.app.job.JobParameters;
+import android.app.job.JobService;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Binder;
-import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
-import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.util.Log;
 
 import com.android.demo.jobSchedulerApp.MainActivity;
 
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.LinkedList;
-import java.util.List;
 
 
 /**
@@ -52,7 +44,7 @@
  * lifecycle of our and provide a handle to said SyncAdapter to the OS on
  * request.
  */
-public class TestJobService extends TaskService {
+public class TestJobService extends JobService {
     private static final String TAG = "SyncService";
 
     @Override
@@ -82,44 +74,44 @@
     }
 
     @Override
-    public boolean onStartTask(TaskParams params) {
-        taskParamsMap.add(params);
+    public boolean onStartJob(JobParameters params) {
+        jobParamsMap.add(params);
         if (mActivity != null) {
-            mActivity.onReceivedStartTask(params);
+            mActivity.onReceivedStartJob(params);
         }
-        Log.i(TAG, "on start task: " + params.getTaskId());
+        Log.i(TAG, "on start job: " + params.getJobId());
         return true;
     }
 
     @Override
-    public boolean onStopTask(TaskParams params) {
-        taskParamsMap.remove(params);
-        mActivity.onReceivedStopTask();
-        Log.i(TAG, "on stop task: " + params.getTaskId());
+    public boolean onStopJob(JobParameters params) {
+        jobParamsMap.remove(params);
+        mActivity.onReceivedStopJob();
+        Log.i(TAG, "on stop job: " + params.getJobId());
         return true;
     }
 
     MainActivity mActivity;
-    private final LinkedList<TaskParams> taskParamsMap = new LinkedList<TaskParams>();
+    private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();
 
     public void setUiCallback(MainActivity activity) {
         mActivity = activity;
     }
 
     /** Send job to the JobScheduler. */
-    public void scheduleJob(Task t) {
+    public void scheduleJob(JobInfo t) {
         Log.d(TAG, "Scheduling job");
-        TaskManager tm =
-                (TaskManager) getSystemService(Context.TASK_SERVICE);
+        JobScheduler tm =
+                (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
         tm.schedule(t);
     }
 
-    public boolean callTaskFinished() {
-        TaskParams params = taskParamsMap.poll();
+    public boolean callJobFinished() {
+        JobParameters params = jobParamsMap.poll();
         if (params == null) {
             return false;
         } else {
-            taskFinished(params, false);
+            jobFinished(params, false);
             return true;
         }
     }
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png
index 84e6bc8..b28624f 100644
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png
index 38e4f45..3f3e288 100644
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png
index bf9f300..06dcd20 100644
--- a/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png
index 782ebfe..e464347 100644
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 677b471..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png
index a1b8062..1b578a6 100644
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index fcdbefe..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png
index 633d864..373e84a 100644
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 4665e2a..0000000
--- a/tools/layoutlib/bridge/resources/bars/ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png
index a00bc5b..f878093 100644
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png
index dc3183b..8e9583b 100644
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png
index b07f611..e2a89c3 100644
--- a/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png
index bd60cd6..ec2951d 100644
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png
index c5bc5c9..254f757 100644
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png
+++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png
index f621d9c..8a8e941 100644
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png
+++ b/tools/layoutlib/bridge/resources/bars/xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index af22f44..36102f1 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -151,7 +151,7 @@
     @Override
     public View inflate(int resource, ViewGroup root) {
         Context context = getContext();
-        if (context instanceof ContextThemeWrapper) {
+        while (context instanceof ContextThemeWrapper) {
             context = ((ContextThemeWrapper) context).getBaseContext();
         }
         if (context instanceof BridgeContext) {
@@ -217,7 +217,7 @@
 
     private void setupViewInContext(View view, AttributeSet attrs) {
         Context context = getContext();
-        if (context instanceof ContextThemeWrapper) {
+        while (context instanceof ContextThemeWrapper) {
             context = ((ContextThemeWrapper) context).getBaseContext();
         }
         if (context instanceof BridgeContext) {
diff --git a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
index 0dddf3d..dafc96b 100644
--- a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
@@ -48,7 +48,7 @@
             AttributeSet attrs) {
         if (menuItem instanceof BridgeMenuItemImpl) {
             Context context = thisInflater.getContext();
-            if (context instanceof ContextThemeWrapper) {
+            while (context instanceof ContextThemeWrapper) {
                 context = ((ContextThemeWrapper) context).getBaseContext();
             }
             if (context instanceof BridgeContext) {
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
index cdb839a..8d1d0c1 100644
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
@@ -42,7 +42,7 @@
             CharSequence title, int showAsAction) {
         super(menu, group, id, categoryOrder, ordering, title, showAsAction);
         Context context = menu.getContext();
-        if (context instanceof ContextThemeWrapper) {
+        while (context instanceof ContextThemeWrapper) {
             context = ((ContextThemeWrapper) context).getBaseContext();
         }
         if (context instanceof BridgeContext) {
diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt
index 6e0a300..32625ae 100644
--- a/tools/layoutlib/create/README.txt
+++ b/tools/layoutlib/create/README.txt
@@ -119,8 +119,8 @@
 
 The class is then fed to RefactorClassAdapter which is like RenameClassAdapter but updates the
 references in all classes. This is used to update the references of classes in the java package that
-were added in the Dalvik VM but are not a part of the standard JVM. The existing classes are
-modified to update all references to these non-standard classes. An alternate implementation of
+were added in the Dalvik VM but are not a part of the Desktop VM. The existing classes are
+modified to update all references to these non-desktop classes. An alternate implementation of
 these (com.android.tools.layoutlib.java.*) is injected.
 
 RenameClassAdapter and RefactorClassAdapter both inherit from AbstractClassAdapter which changes the
@@ -130,11 +130,15 @@
 valid StackMapTable. As a side benefit of this, we can continue to support Java 6 because Java 7 on
 Mac has horrible font rendering support.
 
+ReplaceMethodCallsAdapter replaces calls to certain methods. Currently, it only rewrites calls to
+java.lang.System.arraycopy([CI[CII)V, which is not part of the Desktop VM to call the more general
+method java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V.
+
 The ClassAdapters are chained together to achieve the desired output. (Look at section 2.2.7
 Transformation chains in the asm user guide, link in the References.) The order of execution of
 these is:
 ClassReader -> [DelegateClassAdapter] -> TransformClassAdapter -> [RenameClassAdapter] ->
-RefactorClassAdapter -> ClassWriter
+RefactorClassAdapter -> [ReplaceMethodCallsAdapter] -> ClassWriter
 
 - Method stubs
 --------------
@@ -169,7 +173,7 @@
 - AutoCloseable and Objects are part of Java 7. To enable us to still run on Java 6, new classes are
   injected. The implementation for these classes has been taken from Android's libcore
   (platform/libcore/luni/src/main/java/java/...).
-- Charsets, IntegralToString and UnsafeByteSequence are not part of the standard JAVA VM. They are
+- Charsets, IntegralToString and UnsafeByteSequence are not part of the Desktop VM. They are
   added to the Dalvik VM for performance reasons. An implementation that is very close to the
   original (which is at platform/libcore/luni/src/main/java/...) is injected. Since these classees
   were in part of the java package, where we can't inject classes, all references to these have been
@@ -209,7 +213,7 @@
 
 This is very similar to the Renaming classes except that it also updates the reference in all
 classes. This is done for classes which are added to the Dalvik VM for performance reasons but are
-not present in the Standard Java VM. An implementation for these classes is also injected.
+not present in the Desktop VM. An implementation for these classes is also injected.
 
 
 5- Method erasure based on return type
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
index 3e75c9e..8373e30 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
@@ -32,6 +32,7 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -63,7 +64,8 @@
     private final Set<String> mExcludedClasses;
     /** Glob patterns of files to keep as is. */
     private final String[] mIncludeFileGlobs;
-    /** Copy these files into the output as is. */
+    /** Internal names of classes that contain method calls that need to be rewritten. */
+    private final Set<String> mReplaceMethodCallClasses = new HashSet<String>();
 
     /**
      * Creates a new analyzer.
@@ -109,6 +111,7 @@
             mGen.setKeep(found);
             mGen.setDeps(deps);
             mGen.setCopyFiles(filesFound);
+            mGen.setRewriteMethodCallClasses(mReplaceMethodCallClasses);
         }
     }
 
@@ -118,7 +121,7 @@
      *
      * @param classes The map of class name => ASM ClassReader. Class names are
      *                in the form "android.view.View".
-     * @param fileFound The map of file name => InputStream. The file name is
+     * @param filesFound The map of file name => InputStream. The file name is
      *                  in the form "android/data/dataFile".
      */
     void parseZip(List<String> jarPathList, Map<String, ClassReader> classes,
@@ -143,8 +146,8 @@
                     String className = classReaderToClassName(cr);
                     classes.put(className, cr);
                 } else {
-                    for (int i = 0; i < includeFilePatterns.length; ++i) {
-                        if (includeFilePatterns[i].matcher(entry.getName()).matches()) {
+                    for (Pattern includeFilePattern : includeFilePatterns) {
+                        if (includeFilePattern.matcher(entry.getName()).matches()) {
                             filesFound.put(entry.getName(), zip.getInputStream(entry));
                             break;
                         }
@@ -321,6 +324,7 @@
                 deps, new_deps);
 
         for (ClassReader cr : inOutKeepClasses.values()) {
+            visitor.setClassName(cr.getClassName());
             cr.accept(visitor, 0 /* flags */);
         }
 
@@ -367,6 +371,8 @@
         /** New classes to keep as-is found by this visitor. */
         private final Map<String, ClassReader> mOutKeep;
 
+        private String mClassName;
+
         /**
          * Creates a new visitor that will find all the dependencies for the visited class.
          * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
@@ -390,6 +396,10 @@
             mOutDeps = outDeps;
         }
 
+        private void setClassName(String className) {
+            mClassName = className;
+        }
+
         /**
          * Considers the given class name as a dependency.
          * If it does, add to the mOutDeps map.
@@ -429,7 +439,7 @@
             // - android classes are added to dependencies
             // - non-android classes are added to the list of classes to keep as-is (they don't need
             //   to be stubbed).
-            if (className.indexOf("android") >= 0) {  // TODO make configurable
+            if (className.contains("android")) {  // TODO make configurable
                 mOutDeps.put(className, cr);
             } else {
                 mOutKeep.put(className, cr);
@@ -594,7 +604,7 @@
             // type and exceptions do not use generic types.
             considerSignature(signature);
 
-            return new MyMethodVisitor();
+            return new MyMethodVisitor(mClassName);
         }
 
         @Override
@@ -614,8 +624,11 @@
 
         private class MyMethodVisitor extends MethodVisitor {
 
-            public MyMethodVisitor() {
+            private String mOwnerClass;
+
+            public MyMethodVisitor(String ownerClass) {
                 super(Opcodes.ASM4);
+                mOwnerClass = ownerClass;
             }
 
 
@@ -709,6 +722,13 @@
                 considerName(owner);
                 // desc is the method's descriptor (see Type).
                 considerDesc(desc);
+
+
+                // Check if method is java.lang.System.arrayCopy([CI[CII)V
+                if (owner.equals("java/lang/System") && name.equals("arraycopy")
+                        && desc.equals("([CI[CII)V")) {
+                    mReplaceMethodCallClasses.add(mOwnerClass);
+                }
             }
 
             // instruction multianewarray, whatever that is
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index 207d8ae..c96a143 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -21,7 +21,6 @@
 import org.objectweb.asm.ClassWriter;
 
 import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -55,6 +54,8 @@
     private Map<String, ClassReader> mDeps;
     /** All files that are to be copied as-is. */
     private Map<String, InputStream> mCopyFiles;
+    /** All classes where certain method calls need to be rewritten. */
+    private Set<String> mReplaceMethodCallsClasses;
     /** Counter of number of classes renamed during transform. */
     private int mRenameCount;
     /** FQCN Names of the classes to rename: map old-FQCN => new-FQCN */
@@ -133,7 +134,7 @@
             assert i + 1 < n;
             String oldFqcn = binaryToInternalClassName(refactorClasses[i]);
             String newFqcn = binaryToInternalClassName(refactorClasses[i + 1]);
-            mRefactorClasses.put(oldFqcn, newFqcn);;
+            mRefactorClasses.put(oldFqcn, newFqcn);
         }
 
         // create the map of renamed class -> return type of method to delete.
@@ -203,23 +204,12 @@
         mCopyFiles = copyFiles;
     }
 
-    /** Gets the map of classes to output as-is, except if they have native methods */
-    public Map<String, ClassReader> getKeep() {
-        return mKeep;
-    }
-
-    /** Gets the map of dependencies that must be completely stubbed */
-    public Map<String, ClassReader> getDeps() {
-        return mDeps;
-    }
-
-    /** Gets the map of files to output as-is. */
-    public Map<String, InputStream> getCopyFiles() {
-        return mCopyFiles;
+    public void setRewriteMethodCallClasses(Set<String> rewriteMethodCallClasses) {
+        mReplaceMethodCallsClasses = rewriteMethodCallClasses;
     }
 
     /** Generates the final JAR */
-    public void generate() throws FileNotFoundException, IOException {
+    public void generate() throws IOException {
         TreeMap<String, byte[]> all = new TreeMap<String, byte[]>();
 
         for (Class<?> clazz : mInjectClasses) {
@@ -329,14 +319,14 @@
 
         String newName = transformName(className);
         // transformName returns its input argument if there's no need to rename the class
-        if (newName != className) {
+        if (!newName.equals(className)) {
             mRenameCount++;
             // This class is being renamed, so remove it from the list of classes not renamed.
             mClassesNotRenamed.remove(className);
         }
 
         mLog.debug("Transform %s%s%s%s", className,
-                newName == className ? "" : " (renamed to " + newName + ")",
+                newName.equals(className) ? "" : " (renamed to " + newName + ")",
                 hasNativeMethods ? " -- has natives" : "",
                 stubNativesOnly ? " -- stub natives only" : "");
 
@@ -344,8 +334,14 @@
         // original class reader.
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
 
-        ClassVisitor cv = new RefactorClassAdapter(cw, mRefactorClasses);
-        if (newName != className) {
+        ClassVisitor cv = cw;
+
+        if (mReplaceMethodCallsClasses.contains(className)) {
+            cv = new ReplaceMethodCallsAdapter(cv);
+        }
+
+        cv = new RefactorClassAdapter(cv, mRefactorClasses);
+        if (!newName.equals(className)) {
             cv = new RenameClassAdapter(cv, className, newName);
         }
 
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 2e952fc..ad10656 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
@@ -193,8 +193,7 @@
     private static boolean processArgs(Log log, String[] args,
             ArrayList<String> osJarPath, String[] osDestJar) {
         boolean needs_dest = true;
-        for (int i = 0; i < args.length; i++) {
-            String s = args[i];
+        for (String s : args) {
             if (s.equals("-v")) {
                 log.setVerbose(true);
             } else if (s.equals("-p")) {
@@ -212,7 +211,7 @@
                     osJarPath.add(s);
                 }
             } else {
-                log.error("Unknow argument: %s", s);
+                log.error("Unknown argument: %s", s);
                 return false;
             }
         }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
new file mode 100644
index 0000000..e57eba1
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Replaces calls to certain methods that do not exist in the Desktop VM.
+ */
+public class ReplaceMethodCallsAdapter extends ClassVisitor {
+    public ReplaceMethodCallsAdapter(ClassVisitor cv) {
+        super(Opcodes.ASM4, cv);
+    }
+
+    @Override
+    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
+            String[] exceptions) {
+        return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
+    }
+
+    private class MyMethodVisitor extends MethodVisitor {
+
+        public MyMethodVisitor(MethodVisitor mv) {
+            super(Opcodes.ASM4, mv);
+        }
+
+        @Override
+        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+            // Check if method is java.lang.System.arrayCopy([CI[CII)V
+            if (owner.equals("java/lang/System") && name.equals("arraycopy")
+                    && desc.equals("([CI[CII)V")) {
+                desc = "(Ljava/lang/Object;ILjava/lang/Object;II)V";
+            }
+            super.visitMethodInsn(opcode, owner, name, desc);
+        }
+    }
+}
diff --git a/tools/layoutlib/rename_font/build_font.py b/tools/layoutlib/rename_font/build_font.py
index aea3241..bd9b14c 100755
--- a/tools/layoutlib/rename_font/build_font.py
+++ b/tools/layoutlib/rename_font/build_font.py
@@ -27,7 +27,7 @@
 from fontTools import ttx
 import re
 import os
-from lxml import etree
+import xml.etree.ElementTree as etree
 import shutil
 import glob
 from multiprocessing import Pool
@@ -84,14 +84,13 @@
     ttx.main(ttx_args)
     # now parse the xml file to change its PS name.
     tree = etree.parse(ttx_path)
-    encoding = tree.docinfo.encoding
     root = tree.getroot()
     for name in root.iter('name'):
       [old_ps_name, version] = get_font_info(name)
       if old_ps_name is not None and version is not None:
         new_ps_name = old_ps_name + version
         update_name(name, new_ps_name)
-    tree.write(ttx_path, xml_declaration=True, encoding=encoding )
+    tree.write(ttx_path, xml_declaration=True, encoding='utf-8' )
     # generate the udpated font now.
     ttx_args = ['-q', '-d', dest_dir, ttx_path]
     ttx.main(ttx_args)
diff --git a/tools/layoutlib/rename_font/test.py b/tools/layoutlib/rename_font/test.py
index d4c86cb..b0b69d8 100755
--- a/tools/layoutlib/rename_font/test.py
+++ b/tools/layoutlib/rename_font/test.py
@@ -14,7 +14,7 @@
 
 from fontTools import ttx
 import os
-from lxml import etree
+import xml.etree.ElementTree as etree
 import shutil
 import tempfile