Merge "Fix menu popup rendering" into nyc-dev
diff --git a/Android.mk b/Android.mk
index 59b2a46..c12a8e7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -226,6 +226,7 @@
 	core/java/android/os/INetworkManagementService.aidl \
 	core/java/android/os/IPermissionController.aidl \
 	core/java/android/os/IProcessInfoService.aidl \
+	core/java/android/os/IProgressListener.aidl \
 	core/java/android/os/IPowerManager.aidl \
 	core/java/android/os/IRecoverySystem.aidl \
 	core/java/android/os/IRecoverySystemProgressListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index 3fc1673..adecadb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -301,13 +301,13 @@
     field public static final int backgroundTint = 16843883; // 0x101046b
     field public static final int backgroundTintMode = 16843884; // 0x101046c
     field public static final int backupAgent = 16843391; // 0x101027f
-    field public static final int backupInForeground = 16844059; // 0x101051b
+    field public static final int backupInForeground = 16844060; // 0x101051c
     field public static final int banner = 16843762; // 0x10103f2
     field public static final int baseline = 16843548; // 0x101031c
     field public static final int baselineAlignBottom = 16843042; // 0x1010122
     field public static final int baselineAligned = 16843046; // 0x1010126
     field public static final int baselineAlignedChildIndex = 16843047; // 0x1010127
-    field public static final int bitmap = 16844055; // 0x1010517
+    field public static final int bitmap = 16844056; // 0x1010518
     field public static final int borderlessButtonStyle = 16843563; // 0x101032b
     field public static final int bottom = 16843184; // 0x10101b0
     field public static final int bottomBright = 16842957; // 0x10100cd
@@ -326,7 +326,7 @@
     field public static final int buttonBarNeutralButtonStyle = 16843914; // 0x101048a
     field public static final int buttonBarPositiveButtonStyle = 16843913; // 0x1010489
     field public static final int buttonBarStyle = 16843566; // 0x101032e
-    field public static final int buttonGravity = 16844031; // 0x10104ff
+    field public static final int buttonGravity = 16844032; // 0x1010500
     field public static final int buttonStyle = 16842824; // 0x1010048
     field public static final int buttonStyleInset = 16842826; // 0x101004a
     field public static final int buttonStyleSmall = 16842825; // 0x1010049
@@ -337,9 +337,9 @@
     field public static final int calendarTextColor = 16843931; // 0x101049b
     field public static final int calendarViewShown = 16843596; // 0x101034c
     field public static final int calendarViewStyle = 16843613; // 0x101035d
-    field public static final int canControlMagnification = 16844040; // 0x1010508
-    field public static final int canPerformGestures = 16844046; // 0x101050e
-    field public static final int canRecord = 16844061; // 0x101051d
+    field public static final int canControlMagnification = 16844041; // 0x1010509
+    field public static final int canPerformGestures = 16844047; // 0x101050f
+    field public static final int canRecord = 16844062; // 0x101051e
     field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
     field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
@@ -379,7 +379,7 @@
     field public static final int codes = 16843330; // 0x1010242
     field public static final int collapseColumns = 16843083; // 0x101014b
     field public static final int collapseContentDescription = 16843984; // 0x10104d0
-    field public static final int collapseIcon = 16844032; // 0x1010500
+    field public static final int collapseIcon = 16844033; // 0x1010501
     field public static final int color = 16843173; // 0x10101a5
     field public static final int colorAccent = 16843829; // 0x1010435
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
@@ -420,12 +420,12 @@
     field public static final int contentInsetRight = 16843862; // 0x1010456
     field public static final int contentInsetStart = 16843859; // 0x1010453
     field public static final int contextClickable = 16844007; // 0x10104e7
-    field public static final int contextPopupMenuStyle = 16844034; // 0x1010502
+    field public static final int contextPopupMenuStyle = 16844035; // 0x1010503
     field public static final int controlX1 = 16843772; // 0x10103fc
     field public static final int controlX2 = 16843774; // 0x10103fe
     field public static final int controlY1 = 16843773; // 0x10103fd
     field public static final int controlY2 = 16843775; // 0x10103ff
-    field public static final int countDown = 16844060; // 0x101051c
+    field public static final int countDown = 16844061; // 0x101051d
     field public static final int country = 16843962; // 0x10104ba
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
@@ -443,7 +443,7 @@
     field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
     field public static final int debuggable = 16842767; // 0x101000f
     field public static final int defaultHeight = 16844021; // 0x10104f5
-    field public static final int defaultToDeviceProtectedStorage = 16844037; // 0x1010505
+    field public static final int defaultToDeviceProtectedStorage = 16844038; // 0x1010506
     field public static final int defaultValue = 16843245; // 0x10101ed
     field public static final int defaultWidth = 16844020; // 0x10104f4
     field public static final int delay = 16843212; // 0x10101cc
@@ -463,7 +463,7 @@
     field public static final int dialogTheme = 16843528; // 0x1010308
     field public static final int dialogTitle = 16843250; // 0x10101f2
     field public static final int digits = 16843110; // 0x1010166
-    field public static final int directBootAware = 16844038; // 0x1010506
+    field public static final int directBootAware = 16844039; // 0x1010507
     field public static final int direction = 16843217; // 0x10101d1
     field public static final deprecated int directionDescriptions = 16843681; // 0x10103a1
     field public static final int directionPriority = 16843218; // 0x10101d2
@@ -514,8 +514,8 @@
     field public static final int enabled = 16842766; // 0x101000e
     field public static final int end = 16843996; // 0x10104dc
     field public static final int endColor = 16843166; // 0x101019e
-    field public static final int endX = 16844051; // 0x1010513
-    field public static final int endY = 16844052; // 0x1010514
+    field public static final int endX = 16844052; // 0x1010514
+    field public static final int endY = 16844053; // 0x1010515
     field public static final deprecated int endYear = 16843133; // 0x101017d
     field public static final int enterFadeDuration = 16843532; // 0x101030c
     field public static final int entries = 16842930; // 0x10100b2
@@ -535,7 +535,7 @@
     field public static final int expandableListViewStyle = 16842863; // 0x101006f
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
-    field public static final int externalService = 16844047; // 0x101050f
+    field public static final int externalService = 16844048; // 0x1010510
     field public static final int extraTension = 16843371; // 0x101026b
     field public static final int extractNativeLibs = 16844010; // 0x10104ea
     field public static final int factor = 16843219; // 0x10101d3
@@ -560,7 +560,7 @@
     field public static final int fillBefore = 16843196; // 0x10101bc
     field public static final int fillColor = 16843780; // 0x1010404
     field public static final int fillEnabled = 16843343; // 0x101024f
-    field public static final int fillType = 16844064; // 0x1010520
+    field public static final int fillType = 16844065; // 0x1010521
     field public static final int fillViewport = 16843130; // 0x101017a
     field public static final int filter = 16843035; // 0x101011b
     field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4
@@ -652,8 +652,8 @@
     field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
     field public static final int horizontalSpacing = 16843028; // 0x1010114
     field public static final int host = 16842792; // 0x1010028
-    field public static final int hotSpotX = 16844056; // 0x1010518
-    field public static final int hotSpotY = 16844057; // 0x1010519
+    field public static final int hotSpotX = 16844057; // 0x1010519
+    field public static final int hotSpotY = 16844058; // 0x101051a
     field public static final int hyphenationFrequency = 16843998; // 0x10104de
     field public static final int icon = 16842754; // 0x1010002
     field public static final int iconPreview = 16843337; // 0x1010249
@@ -740,7 +740,7 @@
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
     field public static final int labelTextSize = 16843317; // 0x1010235
-    field public static final int languageTag = 16844041; // 0x1010509
+    field public static final int languageTag = 16844042; // 0x101050a
     field public static final int largeHeap = 16843610; // 0x101035a
     field public static final int largeScreens = 16843398; // 0x1010286
     field public static final int largestWidthLimitDp = 16843622; // 0x1010366
@@ -798,7 +798,7 @@
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
     field public static final int letterSpacing = 16843958; // 0x10104b6
-    field public static final int level = 16844033; // 0x1010501
+    field public static final int level = 16844034; // 0x1010502
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
     field public static final int lines = 16843092; // 0x1010154
@@ -831,7 +831,7 @@
     field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
     field public static final int matchOrder = 16843855; // 0x101044f
     field public static final int max = 16843062; // 0x1010136
-    field public static final int maxButtonHeight = 16844030; // 0x10104fe
+    field public static final int maxButtonHeight = 16844031; // 0x10104ff
     field public static final int maxDate = 16843584; // 0x1010340
     field public static final int maxEms = 16843095; // 0x1010157
     field public static final int maxHeight = 16843040; // 0x1010120
@@ -859,7 +859,8 @@
     field public static final int minResizeWidth = 16843669; // 0x1010395
     field public static final int minSdkVersion = 16843276; // 0x101020c
     field public static final int minWidth = 16843071; // 0x101013f
-    field public static final int minimalSize = 16844022; // 0x10104f6
+    field public static final int minimalHeight = 16844023; // 0x10104f7
+    field public static final int minimalWidth = 16844022; // 0x10104f6
     field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
     field public static final int minimumVerticalAngle = 16843902; // 0x101047e
     field public static final int mipMap = 16843725; // 0x10103cd
@@ -880,7 +881,7 @@
     field public static final int nextFocusLeft = 16842977; // 0x10100e1
     field public static final int nextFocusRight = 16842978; // 0x10100e2
     field public static final int nextFocusUp = 16842979; // 0x10100e3
-    field public static final int nfcAntennaPositionDrawable = 16844063; // 0x101051f
+    field public static final int nfcAntennaPositionDrawable = 16844064; // 0x1010520
     field public static final int noHistory = 16843309; // 0x101022d
     field public static final int normalScreens = 16843397; // 0x1010285
     field public static final int notificationTimeout = 16843651; // 0x1010383
@@ -892,7 +893,7 @@
     field public static final int numbersTextColor = 16843937; // 0x10104a1
     field public static final deprecated int numeric = 16843109; // 0x1010165
     field public static final int numericShortcut = 16843236; // 0x10101e4
-    field public static final int offset = 16844053; // 0x1010515
+    field public static final int offset = 16844054; // 0x1010516
     field public static final int onClick = 16843375; // 0x101026f
     field public static final int oneshot = 16843159; // 0x1010197
     field public static final int opacity = 16843550; // 0x101031e
@@ -939,13 +940,13 @@
     field public static final deprecated int phoneNumber = 16843111; // 0x1010167
     field public static final int pivotX = 16843189; // 0x10101b5
     field public static final int pivotY = 16843190; // 0x10101b6
-    field public static final int pointerShape = 16844042; // 0x101050a
+    field public static final int pointerShape = 16844043; // 0x101050b
     field public static final int popupAnimationStyle = 16843465; // 0x10102c9
     field public static final int popupBackground = 16843126; // 0x1010176
     field public static final int popupCharacters = 16843332; // 0x1010244
     field public static final int popupElevation = 16843916; // 0x101048c
-    field public static final int popupEnterTransition = 16844065; // 0x1010521
-    field public static final int popupExitTransition = 16844066; // 0x1010522
+    field public static final int popupEnterTransition = 16844066; // 0x1010522
+    field public static final int popupExitTransition = 16844067; // 0x1010523
     field public static final int popupKeyboard = 16843331; // 0x1010243
     field public static final int popupLayout = 16843323; // 0x101023b
     field public static final int popupMenuStyle = 16843520; // 0x1010300
@@ -954,7 +955,7 @@
     field public static final int port = 16842793; // 0x1010029
     field public static final int positiveButtonText = 16843253; // 0x10101f5
     field public static final int preferenceCategoryStyle = 16842892; // 0x101008c
-    field public static final int preferenceFragmentStyle = 16844039; // 0x1010507
+    field public static final int preferenceFragmentStyle = 16844040; // 0x1010508
     field public static final int preferenceInformationStyle = 16842893; // 0x101008d
     field public static final int preferenceLayoutChild = 16842900; // 0x1010094
     field public static final int preferenceScreenStyle = 16842891; // 0x101008b
@@ -1022,7 +1023,7 @@
     field public static final int resizeClip = 16843983; // 0x10104cf
     field public static final int resizeMode = 16843619; // 0x1010363
     field public static final int resizeable = 16843405; // 0x101028d
-    field public static final int resizeableActivity = 16844023; // 0x10104f7
+    field public static final int resizeableActivity = 16844024; // 0x10104f8
     field public static final int resource = 16842789; // 0x1010025
     field public static final int restoreAnyVersion = 16843450; // 0x10102ba
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
@@ -1142,8 +1143,8 @@
     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 int startX = 16844049; // 0x1010511
-    field public static final int startY = 16844050; // 0x1010512
+    field public static final int startX = 16844050; // 0x1010512
+    field public static final int startY = 16844051; // 0x1010513
     field public static final deprecated int startYear = 16843132; // 0x101017c
     field public static final int stateListAnimator = 16843848; // 0x1010448
     field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -1200,8 +1201,8 @@
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsAssist = 16844016; // 0x10104f0
     field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
-    field public static final int supportsLocalInteraction = 16844048; // 0x1010510
-    field public static final int supportsPictureInPicture = 16844024; // 0x10104f8
+    field public static final int supportsLocalInteraction = 16844049; // 0x1010511
+    field public static final int supportsPictureInPicture = 16844025; // 0x10104f9
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
     field public static final int supportsUploading = 16843419; // 0x101029b
@@ -1250,7 +1251,7 @@
     field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
     field public static final int textAppearanceMedium = 16842817; // 0x1010041
     field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
-    field public static final int textAppearancePopupMenuHeader = 16844035; // 0x1010503
+    field public static final int textAppearancePopupMenuHeader = 16844036; // 0x1010504
     field public static final int textAppearanceSearchResultSubtitle = 16843424; // 0x10102a0
     field public static final int textAppearanceSearchResultTitle = 16843425; // 0x10102a1
     field public static final int textAppearanceSmall = 16842818; // 0x1010042
@@ -1308,9 +1309,9 @@
     field public static final int thumbTint = 16843889; // 0x1010471
     field public static final int thumbTintMode = 16843890; // 0x1010472
     field public static final int thumbnail = 16843429; // 0x10102a5
-    field public static final int tickMark = 16844043; // 0x101050b
-    field public static final int tickMarkTint = 16844044; // 0x101050c
-    field public static final int tickMarkTintMode = 16844045; // 0x101050d
+    field public static final int tickMark = 16844044; // 0x101050c
+    field public static final int tickMarkTint = 16844045; // 0x101050d
+    field public static final int tickMarkTintMode = 16844046; // 0x101050e
     field public static final int tileMode = 16843265; // 0x1010201
     field public static final int tileModeX = 16843895; // 0x1010477
     field public static final int tileModeY = 16843896; // 0x1010478
@@ -1322,11 +1323,11 @@
     field public static final int tintMode = 16843771; // 0x10103fb
     field public static final int title = 16843233; // 0x10101e1
     field public static final int titleCondensed = 16843234; // 0x10101e2
-    field public static final int titleMargin = 16844025; // 0x10104f9
-    field public static final int titleMarginBottom = 16844029; // 0x10104fd
-    field public static final int titleMarginEnd = 16844027; // 0x10104fb
-    field public static final int titleMarginStart = 16844026; // 0x10104fa
-    field public static final int titleMarginTop = 16844028; // 0x10104fc
+    field public static final int titleMargin = 16844026; // 0x10104fa
+    field public static final int titleMarginBottom = 16844030; // 0x10104fe
+    field public static final int titleMarginEnd = 16844028; // 0x10104fc
+    field public static final int titleMarginStart = 16844027; // 0x10104fb
+    field public static final int titleMarginTop = 16844029; // 0x10104fd
     field public static final int titleTextAppearance = 16843822; // 0x101042e
     field public static final int titleTextColor = 16844003; // 0x10104e3
     field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -1365,7 +1366,7 @@
     field public static final int trimPathEnd = 16843785; // 0x1010409
     field public static final int trimPathOffset = 16843786; // 0x101040a
     field public static final int trimPathStart = 16843784; // 0x1010408
-    field public static final int tunerCount = 16844062; // 0x101051e
+    field public static final int tunerCount = 16844063; // 0x101051f
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -1373,7 +1374,7 @@
     field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
-    field public static final int use32bitAbi = 16844054; // 0x1010516
+    field public static final int use32bitAbi = 16844055; // 0x1010517
     field public static final int useDefaultMargins = 16843641; // 0x1010379
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
@@ -1385,7 +1386,7 @@
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
     field public static final int vendor = 16843751; // 0x10103e7
-    field public static final int version = 16844058; // 0x101051a
+    field public static final int version = 16844059; // 0x101051b
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -1429,7 +1430,7 @@
     field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b
     field public static final int windowAnimationStyle = 16842926; // 0x10100ae
     field public static final int windowBackground = 16842836; // 0x1010054
-    field public static final int windowBackgroundFallback = 16844036; // 0x1010504
+    field public static final int windowBackgroundFallback = 16844037; // 0x1010505
     field public static final int windowClipToOutline = 16843947; // 0x10104ab
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
     field public static final int windowContentOverlay = 16842841; // 0x1010059
@@ -4280,6 +4281,7 @@
 
   public class DownloadManager {
     method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean);
+    method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean, android.net.Uri, android.net.Uri);
     method public long enqueue(android.app.DownloadManager.Request);
     method public static java.lang.Long getMaxBytesOverMobile(android.content.Context);
     method public java.lang.String getMimeTypeForDownloadedFile(long);
@@ -9256,7 +9258,6 @@
     field public int documentLaunchMode;
     field public int flags;
     field public int launchMode;
-    field public android.content.pm.ActivityInfo.Layout layout;
     field public int maxRecents;
     field public java.lang.String parentActivityName;
     field public java.lang.String permission;
@@ -9267,14 +9268,16 @@
     field public java.lang.String taskAffinity;
     field public int theme;
     field public int uiOptions;
+    field public android.content.pm.ActivityInfo.WindowLayout windowLayout;
   }
 
-  public static final class ActivityInfo.Layout {
-    ctor public ActivityInfo.Layout(int, float, int, float, int, int);
+  public static final class ActivityInfo.WindowLayout {
+    ctor public ActivityInfo.WindowLayout(int, float, int, float, int, int, int);
     field public final int gravity;
     field public final int height;
     field public final float heightFraction;
-    field public final int minimalSize;
+    field public final int minimalHeight;
+    field public final int minimalWidth;
     field public final int width;
     field public final float widthFraction;
   }
@@ -22280,7 +22283,7 @@
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
-    method public void unsubscribe(java.lang.String, android.os.Bundle);
+    method public void unsubscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
     field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
   }
@@ -23053,6 +23056,7 @@
     method public abstract void onStartRecording(android.net.Uri);
     method public abstract void onStopRecording();
     method public abstract void onTune(android.net.Uri);
+    method public void onTune(android.net.Uri, android.os.Bundle);
   }
 
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
@@ -23102,6 +23106,7 @@
     method public void startRecording(android.net.Uri);
     method public void stopRecording();
     method public void tune(java.lang.String, android.net.Uri);
+    method public void tune(java.lang.String, android.net.Uri, android.os.Bundle);
   }
 
   public static abstract class TvRecordingClient.RecordingCallback {
@@ -29564,8 +29569,8 @@
 
   public class StorageManager {
     method public java.lang.String getMountedObbPath(java.lang.String);
-    method public android.os.storage.StorageVolume getPrimaryVolume();
-    method public android.os.storage.StorageVolume[] getVolumeList();
+    method public android.os.storage.StorageVolume getPrimaryStorageVolume();
+    method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
     method public boolean isEncrypted(java.io.File);
     method public boolean isObbMounted(java.lang.String);
     method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
@@ -29893,6 +29898,8 @@
     method public android.content.SharedPreferences getSharedPreferences();
     method public int getSharedPreferencesMode();
     method public java.lang.String getSharedPreferencesName();
+    method public boolean isStorageDefault();
+    method public boolean isStorageDeviceProtected();
     method public static void setDefaultValues(android.content.Context, int, boolean);
     method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
     method public void setSharedPreferencesMode(int);
@@ -30268,7 +30275,7 @@
     method public android.print.PrinterInfo build();
     method public android.print.PrinterInfo.Builder setCapabilities(android.print.PrinterCapabilitiesInfo);
     method public android.print.PrinterInfo.Builder setDescription(java.lang.String);
-    method public android.print.PrinterInfo.Builder setHasCustomPrinterIcon();
+    method public android.print.PrinterInfo.Builder setHasCustomPrinterIcon(boolean);
     method public android.print.PrinterInfo.Builder setIconResourceId(int);
     method public android.print.PrinterInfo.Builder setInfoIntent(android.app.PendingIntent);
     method public android.print.PrinterInfo.Builder setName(java.lang.String);
@@ -30320,6 +30327,7 @@
     method public boolean isStarted();
     method public void setProgress(float);
     method public void setStatus(java.lang.CharSequence);
+    method public void setStatus(int);
     method public boolean setTag(java.lang.String);
     method public boolean start();
   }
@@ -30396,6 +30404,7 @@
   public class BlockedNumberContract {
     method public static boolean canCurrentUserBlockNumbers(android.content.Context);
     method public static boolean isBlocked(android.content.Context, java.lang.String);
+    method public static int unblock(android.content.Context, java.lang.String);
     field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
     field public static final android.net.Uri AUTHORITY_URI;
   }
@@ -32388,6 +32397,7 @@
     field public static final java.lang.String ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE = "android.settings.VOICE_CONTROL_BATTERY_SAVER_MODE";
     field public static final java.lang.String ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE = "android.settings.VOICE_CONTROL_DO_NOT_DISTURB_MODE";
     field public static final java.lang.String ACTION_VOICE_INPUT_SETTINGS = "android.settings.VOICE_INPUT_SETTINGS";
+    field public static final java.lang.String ACTION_VPN_SETTINGS = "android.settings.VPN_SETTINGS";
     field public static final java.lang.String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS";
@@ -34577,7 +34587,6 @@
     method public boolean onMenuOpened(int, android.view.Menu);
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
-    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -36008,9 +36017,11 @@
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
     method public void pullExternalCall();
+    method public final void putExtras(android.os.Bundle);
     method public void registerCallback(android.telecom.Call.Callback);
     method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
     method public void reject(boolean, java.lang.String);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public void sendCallEvent(java.lang.String, android.os.Bundle);
     method public void splitFromConference();
     method public void stopDtmfTone();
@@ -36139,6 +36150,7 @@
     method public final android.telecom.CallAudioState getCallAudioState();
     method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final long getConnectionTime();
     method public final java.util.List<android.telecom.Connection> getConnections();
     method public final android.telecom.DisconnectCause getDisconnectCause();
@@ -36151,6 +36163,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onConnectionAdded(android.telecom.Connection);
     method public void onDisconnect();
+    method public void onExtrasChanged(android.os.Bundle);
     method public void onHold();
     method public void onMerge(android.telecom.Connection);
     method public void onMerge();
@@ -36159,14 +36172,17 @@
     method public void onStopDtmfTone();
     method public void onSwap();
     method public void onUnhold();
+    method public final void putExtras(android.os.Bundle);
     method public final void removeConnection(android.telecom.Connection);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public final void setActive();
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionProperties(int);
     method public final void setConnectionTime(long);
     method public final void setDialing();
     method public final void setDisconnected(android.telecom.DisconnectCause);
-    method public final void setExtras(android.os.Bundle);
+    method public final deprecated void setExtras(android.os.Bundle);
     method public final void setOnHold();
     method public final void setStatusHints(android.telecom.StatusHints);
     method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
@@ -36192,6 +36208,7 @@
     method public final android.telecom.Conference getConference();
     method public final java.util.List<android.telecom.Conferenceable> getConferenceables();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
     method public final int getState();
@@ -36204,6 +36221,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onCallEvent(java.lang.String, android.os.Bundle);
     method public void onDisconnect();
+    method public void onExtrasChanged(android.os.Bundle);
     method public void onHold();
     method public void onPlayDtmfTone(char);
     method public void onPostDialContinue(boolean);
@@ -36214,6 +36232,9 @@
     method public void onStateChanged(int);
     method public void onStopDtmfTone();
     method public void onUnhold();
+    method public static java.lang.String propertiesToString(int);
+    method public final void putExtras(android.os.Bundle);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -36222,9 +36243,10 @@
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConferenceables(java.util.List<android.telecom.Conferenceable>);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionProperties(int);
     method public final void setDialing();
     method public final void setDisconnected(android.telecom.DisconnectCause);
-    method public final void setExtras(android.os.Bundle);
+    method public final deprecated void setExtras(android.os.Bundle);
     method public final void setInitialized();
     method public final void setInitializing();
     method public final void setNextPostDialChar(char);
@@ -36238,12 +36260,11 @@
     method public static java.lang.String stateToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
-    field public static final int CAPABILITY_CAN_PULL_CALL = 33554432; // 0x2000000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
-    field public static final int CAPABILITY_IS_EXTERNAL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
     field public static final int CAPABILITY_MERGE_CONFERENCE = 4; // 0x4
     field public static final int CAPABILITY_MUTE = 64; // 0x40
@@ -36261,6 +36282,7 @@
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
+    field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_DIALING = 3; // 0x3
     field public static final int STATE_DISCONNECTED = 6; // 0x6
@@ -36483,6 +36505,7 @@
     method public void disconnect();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final java.util.List<android.telecom.RemoteConnection> getConnections();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
@@ -36505,6 +36528,7 @@
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConference, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionAdded(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConference, int);
+    method public void onConnectionPropertiesChanged(android.telecom.RemoteConference, int);
     method public void onConnectionRemoved(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onDestroyed(android.telecom.RemoteConference);
     method public void onDisconnected(android.telecom.RemoteConference, android.telecom.DisconnectCause);
@@ -36523,6 +36547,7 @@
     method public android.telecom.RemoteConference getConference();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
     method public int getConnectionCapabilities();
+    method public int getConnectionProperties();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
     method public int getState();
@@ -36552,6 +36577,7 @@
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConnection, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConnection, int);
     method public void onConnectionEvent(android.telecom.RemoteConnection, java.lang.String, android.os.Bundle);
+    method public void onConnectionPropertiesChanged(android.telecom.RemoteConnection, int);
     method public void onDestroyed(android.telecom.RemoteConnection);
     method public void onDisconnected(android.telecom.RemoteConnection, android.telecom.DisconnectCause);
     method public void onExtrasChanged(android.telecom.RemoteConnection, android.os.Bundle);
@@ -41641,9 +41667,11 @@
   }
 
   public final class KeyboardShortcutInfo implements android.os.Parcelable {
+    ctor public KeyboardShortcutInfo(java.lang.CharSequence, int, int);
     ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
     method public int describeContents();
     method public char getBaseCharacter();
+    method public int getKeycode();
     method public java.lang.CharSequence getLabel();
     method public int getModifiers();
     method public void writeToParcel(android.os.Parcel, int);
@@ -43654,7 +43682,7 @@
     method public abstract boolean onMenuOpened(int, android.view.Menu);
     method public abstract void onPanelClosed(int, android.view.Menu);
     method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
-    method public default void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
+    method public default void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu, int);
     method public abstract boolean onSearchRequested();
     method public abstract boolean onSearchRequested(android.view.SearchEvent);
     method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -51114,41 +51142,11 @@
     method public java.io.File directory();
     method public java.lang.ProcessBuilder directory(java.io.File);
     method public java.util.Map<java.lang.String, java.lang.String> environment();
-    method public java.lang.ProcessBuilder inheritIO();
-    method public java.lang.ProcessBuilder redirectError(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectError(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectError();
     method public boolean redirectErrorStream();
     method public java.lang.ProcessBuilder redirectErrorStream(boolean);
-    method public java.lang.ProcessBuilder redirectInput(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectInput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectInput();
-    method public java.lang.ProcessBuilder redirectOutput(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectOutput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectOutput();
     method public java.lang.Process start() throws java.io.IOException;
   }
 
-  public static abstract class ProcessBuilder.Redirect {
-    method public static java.lang.ProcessBuilder.Redirect appendTo(java.io.File);
-    method public java.io.File file();
-    method public static java.lang.ProcessBuilder.Redirect from(java.io.File);
-    method public static java.lang.ProcessBuilder.Redirect to(java.io.File);
-    method public abstract java.lang.ProcessBuilder.Redirect.Type type();
-    field public static final java.lang.ProcessBuilder.Redirect INHERIT;
-    field public static final java.lang.ProcessBuilder.Redirect PIPE;
-  }
-
-  public static final class ProcessBuilder.Redirect.Type extends java.lang.Enum {
-    method public static java.lang.ProcessBuilder.Redirect.Type valueOf(java.lang.String);
-    method public static final java.lang.ProcessBuilder.Redirect.Type[] values();
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type APPEND;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type INHERIT;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type PIPE;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type READ;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type WRITE;
-  }
-
   public abstract interface Readable {
     method public abstract int read(java.nio.CharBuffer) throws java.io.IOException;
   }
@@ -57407,6 +57405,10 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
+    method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
+    method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
+    method public static void parallelSetAll(double[], java.util.function.IntToDoubleFunction);
     method public static void parallelSort(byte[]);
     method public static void parallelSort(byte[], int, int);
     method public static void parallelSort(char[]);
@@ -66421,4 +66423,3 @@
   }
 
 }
-
diff --git a/api/removed.txt b/api/removed.txt
index 36c8ce5..86085c8 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -136,6 +136,15 @@
 
 }
 
+package android.os.storage {
+
+  public class StorageManager {
+    method public android.os.storage.StorageVolume getPrimaryVolume();
+    method public android.os.storage.StorageVolume[] getVolumeList();
+  }
+
+}
+
 package android.preference {
 
   public class PreferenceManager {
diff --git a/api/system-current.txt b/api/system-current.txt
index 48e1bd0..11b34dc 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -396,13 +396,13 @@
     field public static final int backgroundTint = 16843883; // 0x101046b
     field public static final int backgroundTintMode = 16843884; // 0x101046c
     field public static final int backupAgent = 16843391; // 0x101027f
-    field public static final int backupInForeground = 16844059; // 0x101051b
+    field public static final int backupInForeground = 16844060; // 0x101051c
     field public static final int banner = 16843762; // 0x10103f2
     field public static final int baseline = 16843548; // 0x101031c
     field public static final int baselineAlignBottom = 16843042; // 0x1010122
     field public static final int baselineAligned = 16843046; // 0x1010126
     field public static final int baselineAlignedChildIndex = 16843047; // 0x1010127
-    field public static final int bitmap = 16844055; // 0x1010517
+    field public static final int bitmap = 16844056; // 0x1010518
     field public static final int borderlessButtonStyle = 16843563; // 0x101032b
     field public static final int bottom = 16843184; // 0x10101b0
     field public static final int bottomBright = 16842957; // 0x10100cd
@@ -421,7 +421,7 @@
     field public static final int buttonBarNeutralButtonStyle = 16843914; // 0x101048a
     field public static final int buttonBarPositiveButtonStyle = 16843913; // 0x1010489
     field public static final int buttonBarStyle = 16843566; // 0x101032e
-    field public static final int buttonGravity = 16844031; // 0x10104ff
+    field public static final int buttonGravity = 16844032; // 0x1010500
     field public static final int buttonStyle = 16842824; // 0x1010048
     field public static final int buttonStyleInset = 16842826; // 0x101004a
     field public static final int buttonStyleSmall = 16842825; // 0x1010049
@@ -432,9 +432,9 @@
     field public static final int calendarTextColor = 16843931; // 0x101049b
     field public static final int calendarViewShown = 16843596; // 0x101034c
     field public static final int calendarViewStyle = 16843613; // 0x101035d
-    field public static final int canControlMagnification = 16844040; // 0x1010508
-    field public static final int canPerformGestures = 16844046; // 0x101050e
-    field public static final int canRecord = 16844061; // 0x101051d
+    field public static final int canControlMagnification = 16844041; // 0x1010509
+    field public static final int canPerformGestures = 16844047; // 0x101050f
+    field public static final int canRecord = 16844062; // 0x101051e
     field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
     field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
@@ -474,7 +474,7 @@
     field public static final int codes = 16843330; // 0x1010242
     field public static final int collapseColumns = 16843083; // 0x101014b
     field public static final int collapseContentDescription = 16843984; // 0x10104d0
-    field public static final int collapseIcon = 16844032; // 0x1010500
+    field public static final int collapseIcon = 16844033; // 0x1010501
     field public static final int color = 16843173; // 0x10101a5
     field public static final int colorAccent = 16843829; // 0x1010435
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
@@ -515,12 +515,12 @@
     field public static final int contentInsetRight = 16843862; // 0x1010456
     field public static final int contentInsetStart = 16843859; // 0x1010453
     field public static final int contextClickable = 16844007; // 0x10104e7
-    field public static final int contextPopupMenuStyle = 16844034; // 0x1010502
+    field public static final int contextPopupMenuStyle = 16844035; // 0x1010503
     field public static final int controlX1 = 16843772; // 0x10103fc
     field public static final int controlX2 = 16843774; // 0x10103fe
     field public static final int controlY1 = 16843773; // 0x10103fd
     field public static final int controlY2 = 16843775; // 0x10103ff
-    field public static final int countDown = 16844060; // 0x101051c
+    field public static final int countDown = 16844061; // 0x101051d
     field public static final int country = 16843962; // 0x10104ba
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
@@ -538,7 +538,7 @@
     field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
     field public static final int debuggable = 16842767; // 0x101000f
     field public static final int defaultHeight = 16844021; // 0x10104f5
-    field public static final int defaultToDeviceProtectedStorage = 16844037; // 0x1010505
+    field public static final int defaultToDeviceProtectedStorage = 16844038; // 0x1010506
     field public static final int defaultValue = 16843245; // 0x10101ed
     field public static final int defaultWidth = 16844020; // 0x10104f4
     field public static final int delay = 16843212; // 0x10101cc
@@ -558,7 +558,7 @@
     field public static final int dialogTheme = 16843528; // 0x1010308
     field public static final int dialogTitle = 16843250; // 0x10101f2
     field public static final int digits = 16843110; // 0x1010166
-    field public static final int directBootAware = 16844038; // 0x1010506
+    field public static final int directBootAware = 16844039; // 0x1010507
     field public static final int direction = 16843217; // 0x10101d1
     field public static final deprecated int directionDescriptions = 16843681; // 0x10103a1
     field public static final int directionPriority = 16843218; // 0x10101d2
@@ -609,8 +609,8 @@
     field public static final int enabled = 16842766; // 0x101000e
     field public static final int end = 16843996; // 0x10104dc
     field public static final int endColor = 16843166; // 0x101019e
-    field public static final int endX = 16844051; // 0x1010513
-    field public static final int endY = 16844052; // 0x1010514
+    field public static final int endX = 16844052; // 0x1010514
+    field public static final int endY = 16844053; // 0x1010515
     field public static final deprecated int endYear = 16843133; // 0x101017d
     field public static final int enterFadeDuration = 16843532; // 0x101030c
     field public static final int entries = 16842930; // 0x10100b2
@@ -630,7 +630,7 @@
     field public static final int expandableListViewStyle = 16842863; // 0x101006f
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
-    field public static final int externalService = 16844047; // 0x101050f
+    field public static final int externalService = 16844048; // 0x1010510
     field public static final int extraTension = 16843371; // 0x101026b
     field public static final int extractNativeLibs = 16844010; // 0x10104ea
     field public static final int factor = 16843219; // 0x10101d3
@@ -655,7 +655,7 @@
     field public static final int fillBefore = 16843196; // 0x10101bc
     field public static final int fillColor = 16843780; // 0x1010404
     field public static final int fillEnabled = 16843343; // 0x101024f
-    field public static final int fillType = 16844064; // 0x1010520
+    field public static final int fillType = 16844065; // 0x1010521
     field public static final int fillViewport = 16843130; // 0x101017a
     field public static final int filter = 16843035; // 0x101011b
     field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4
@@ -747,8 +747,8 @@
     field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
     field public static final int horizontalSpacing = 16843028; // 0x1010114
     field public static final int host = 16842792; // 0x1010028
-    field public static final int hotSpotX = 16844056; // 0x1010518
-    field public static final int hotSpotY = 16844057; // 0x1010519
+    field public static final int hotSpotX = 16844057; // 0x1010519
+    field public static final int hotSpotY = 16844058; // 0x101051a
     field public static final int hyphenationFrequency = 16843998; // 0x10104de
     field public static final int icon = 16842754; // 0x1010002
     field public static final int iconPreview = 16843337; // 0x1010249
@@ -835,7 +835,7 @@
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
     field public static final int labelTextSize = 16843317; // 0x1010235
-    field public static final int languageTag = 16844041; // 0x1010509
+    field public static final int languageTag = 16844042; // 0x101050a
     field public static final int largeHeap = 16843610; // 0x101035a
     field public static final int largeScreens = 16843398; // 0x1010286
     field public static final int largestWidthLimitDp = 16843622; // 0x1010366
@@ -893,7 +893,7 @@
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
     field public static final int letterSpacing = 16843958; // 0x10104b6
-    field public static final int level = 16844033; // 0x1010501
+    field public static final int level = 16844034; // 0x1010502
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
     field public static final int lines = 16843092; // 0x1010154
@@ -926,7 +926,7 @@
     field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
     field public static final int matchOrder = 16843855; // 0x101044f
     field public static final int max = 16843062; // 0x1010136
-    field public static final int maxButtonHeight = 16844030; // 0x10104fe
+    field public static final int maxButtonHeight = 16844031; // 0x10104ff
     field public static final int maxDate = 16843584; // 0x1010340
     field public static final int maxEms = 16843095; // 0x1010157
     field public static final int maxHeight = 16843040; // 0x1010120
@@ -954,7 +954,8 @@
     field public static final int minResizeWidth = 16843669; // 0x1010395
     field public static final int minSdkVersion = 16843276; // 0x101020c
     field public static final int minWidth = 16843071; // 0x101013f
-    field public static final int minimalSize = 16844022; // 0x10104f6
+    field public static final int minimalHeight = 16844023; // 0x10104f7
+    field public static final int minimalWidth = 16844022; // 0x10104f6
     field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
     field public static final int minimumVerticalAngle = 16843902; // 0x101047e
     field public static final int mipMap = 16843725; // 0x10103cd
@@ -975,7 +976,7 @@
     field public static final int nextFocusLeft = 16842977; // 0x10100e1
     field public static final int nextFocusRight = 16842978; // 0x10100e2
     field public static final int nextFocusUp = 16842979; // 0x10100e3
-    field public static final int nfcAntennaPositionDrawable = 16844063; // 0x101051f
+    field public static final int nfcAntennaPositionDrawable = 16844064; // 0x1010520
     field public static final int noHistory = 16843309; // 0x101022d
     field public static final int normalScreens = 16843397; // 0x1010285
     field public static final int notificationTimeout = 16843651; // 0x1010383
@@ -987,7 +988,7 @@
     field public static final int numbersTextColor = 16843937; // 0x10104a1
     field public static final deprecated int numeric = 16843109; // 0x1010165
     field public static final int numericShortcut = 16843236; // 0x10101e4
-    field public static final int offset = 16844053; // 0x1010515
+    field public static final int offset = 16844054; // 0x1010516
     field public static final int onClick = 16843375; // 0x101026f
     field public static final int oneshot = 16843159; // 0x1010197
     field public static final int opacity = 16843550; // 0x101031e
@@ -1034,13 +1035,13 @@
     field public static final deprecated int phoneNumber = 16843111; // 0x1010167
     field public static final int pivotX = 16843189; // 0x10101b5
     field public static final int pivotY = 16843190; // 0x10101b6
-    field public static final int pointerShape = 16844042; // 0x101050a
+    field public static final int pointerShape = 16844043; // 0x101050b
     field public static final int popupAnimationStyle = 16843465; // 0x10102c9
     field public static final int popupBackground = 16843126; // 0x1010176
     field public static final int popupCharacters = 16843332; // 0x1010244
     field public static final int popupElevation = 16843916; // 0x101048c
-    field public static final int popupEnterTransition = 16844065; // 0x1010521
-    field public static final int popupExitTransition = 16844066; // 0x1010522
+    field public static final int popupEnterTransition = 16844066; // 0x1010522
+    field public static final int popupExitTransition = 16844067; // 0x1010523
     field public static final int popupKeyboard = 16843331; // 0x1010243
     field public static final int popupLayout = 16843323; // 0x101023b
     field public static final int popupMenuStyle = 16843520; // 0x1010300
@@ -1049,7 +1050,7 @@
     field public static final int port = 16842793; // 0x1010029
     field public static final int positiveButtonText = 16843253; // 0x10101f5
     field public static final int preferenceCategoryStyle = 16842892; // 0x101008c
-    field public static final int preferenceFragmentStyle = 16844039; // 0x1010507
+    field public static final int preferenceFragmentStyle = 16844040; // 0x1010508
     field public static final int preferenceInformationStyle = 16842893; // 0x101008d
     field public static final int preferenceLayoutChild = 16842900; // 0x1010094
     field public static final int preferenceScreenStyle = 16842891; // 0x101008b
@@ -1117,7 +1118,7 @@
     field public static final int resizeClip = 16843983; // 0x10104cf
     field public static final int resizeMode = 16843619; // 0x1010363
     field public static final int resizeable = 16843405; // 0x101028d
-    field public static final int resizeableActivity = 16844023; // 0x10104f7
+    field public static final int resizeableActivity = 16844024; // 0x10104f8
     field public static final int resource = 16842789; // 0x1010025
     field public static final int restoreAnyVersion = 16843450; // 0x10102ba
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
@@ -1241,8 +1242,8 @@
     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 int startX = 16844049; // 0x1010511
-    field public static final int startY = 16844050; // 0x1010512
+    field public static final int startX = 16844050; // 0x1010512
+    field public static final int startY = 16844051; // 0x1010513
     field public static final deprecated int startYear = 16843132; // 0x101017c
     field public static final int stateListAnimator = 16843848; // 0x1010448
     field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -1299,8 +1300,8 @@
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsAssist = 16844016; // 0x10104f0
     field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
-    field public static final int supportsLocalInteraction = 16844048; // 0x1010510
-    field public static final int supportsPictureInPicture = 16844024; // 0x10104f8
+    field public static final int supportsLocalInteraction = 16844049; // 0x1010511
+    field public static final int supportsPictureInPicture = 16844025; // 0x10104f9
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
     field public static final int supportsUploading = 16843419; // 0x101029b
@@ -1349,7 +1350,7 @@
     field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
     field public static final int textAppearanceMedium = 16842817; // 0x1010041
     field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
-    field public static final int textAppearancePopupMenuHeader = 16844035; // 0x1010503
+    field public static final int textAppearancePopupMenuHeader = 16844036; // 0x1010504
     field public static final int textAppearanceSearchResultSubtitle = 16843424; // 0x10102a0
     field public static final int textAppearanceSearchResultTitle = 16843425; // 0x10102a1
     field public static final int textAppearanceSmall = 16842818; // 0x1010042
@@ -1407,9 +1408,9 @@
     field public static final int thumbTint = 16843889; // 0x1010471
     field public static final int thumbTintMode = 16843890; // 0x1010472
     field public static final int thumbnail = 16843429; // 0x10102a5
-    field public static final int tickMark = 16844043; // 0x101050b
-    field public static final int tickMarkTint = 16844044; // 0x101050c
-    field public static final int tickMarkTintMode = 16844045; // 0x101050d
+    field public static final int tickMark = 16844044; // 0x101050c
+    field public static final int tickMarkTint = 16844045; // 0x101050d
+    field public static final int tickMarkTintMode = 16844046; // 0x101050e
     field public static final int tileMode = 16843265; // 0x1010201
     field public static final int tileModeX = 16843895; // 0x1010477
     field public static final int tileModeY = 16843896; // 0x1010478
@@ -1421,11 +1422,11 @@
     field public static final int tintMode = 16843771; // 0x10103fb
     field public static final int title = 16843233; // 0x10101e1
     field public static final int titleCondensed = 16843234; // 0x10101e2
-    field public static final int titleMargin = 16844025; // 0x10104f9
-    field public static final int titleMarginBottom = 16844029; // 0x10104fd
-    field public static final int titleMarginEnd = 16844027; // 0x10104fb
-    field public static final int titleMarginStart = 16844026; // 0x10104fa
-    field public static final int titleMarginTop = 16844028; // 0x10104fc
+    field public static final int titleMargin = 16844026; // 0x10104fa
+    field public static final int titleMarginBottom = 16844030; // 0x10104fe
+    field public static final int titleMarginEnd = 16844028; // 0x10104fc
+    field public static final int titleMarginStart = 16844027; // 0x10104fb
+    field public static final int titleMarginTop = 16844029; // 0x10104fd
     field public static final int titleTextAppearance = 16843822; // 0x101042e
     field public static final int titleTextColor = 16844003; // 0x10104e3
     field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -1464,7 +1465,7 @@
     field public static final int trimPathEnd = 16843785; // 0x1010409
     field public static final int trimPathOffset = 16843786; // 0x101040a
     field public static final int trimPathStart = 16843784; // 0x1010408
-    field public static final int tunerCount = 16844062; // 0x101051e
+    field public static final int tunerCount = 16844063; // 0x101051f
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -1472,7 +1473,7 @@
     field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
-    field public static final int use32bitAbi = 16844054; // 0x1010516
+    field public static final int use32bitAbi = 16844055; // 0x1010517
     field public static final int useDefaultMargins = 16843641; // 0x1010379
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
@@ -1484,7 +1485,7 @@
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
     field public static final int vendor = 16843751; // 0x10103e7
-    field public static final int version = 16844058; // 0x101051a
+    field public static final int version = 16844059; // 0x101051b
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -1528,7 +1529,7 @@
     field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b
     field public static final int windowAnimationStyle = 16842926; // 0x10100ae
     field public static final int windowBackground = 16842836; // 0x1010054
-    field public static final int windowBackgroundFallback = 16844036; // 0x1010504
+    field public static final int windowBackgroundFallback = 16844037; // 0x1010505
     field public static final int windowClipToOutline = 16843947; // 0x10104ab
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
     field public static final int windowContentOverlay = 16842841; // 0x1010059
@@ -4412,6 +4413,7 @@
 
   public class DownloadManager {
     method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean);
+    method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean, android.net.Uri, android.net.Uri);
     method public long enqueue(android.app.DownloadManager.Request);
     method public static java.lang.Long getMaxBytesOverMobile(android.content.Context);
     method public java.lang.String getMimeTypeForDownloadedFile(long);
@@ -9579,7 +9581,6 @@
     field public int documentLaunchMode;
     field public int flags;
     field public int launchMode;
-    field public android.content.pm.ActivityInfo.Layout layout;
     field public int maxRecents;
     field public java.lang.String parentActivityName;
     field public java.lang.String permission;
@@ -9590,14 +9591,16 @@
     field public java.lang.String taskAffinity;
     field public int theme;
     field public int uiOptions;
+    field public android.content.pm.ActivityInfo.WindowLayout windowLayout;
   }
 
-  public static final class ActivityInfo.Layout {
-    ctor public ActivityInfo.Layout(int, float, int, float, int, int);
+  public static final class ActivityInfo.WindowLayout {
+    ctor public ActivityInfo.WindowLayout(int, float, int, float, int, int, int);
     field public final int gravity;
     field public final int height;
     field public final float heightFraction;
-    field public final int minimalSize;
+    field public final int minimalHeight;
+    field public final int minimalWidth;
     field public final int width;
     field public final float widthFraction;
   }
@@ -23845,7 +23848,7 @@
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
-    method public void unsubscribe(java.lang.String, android.os.Bundle);
+    method public void unsubscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
     field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
   }
@@ -31878,8 +31881,8 @@
 
   public class StorageManager {
     method public java.lang.String getMountedObbPath(java.lang.String);
-    method public android.os.storage.StorageVolume getPrimaryVolume();
-    method public android.os.storage.StorageVolume[] getVolumeList();
+    method public android.os.storage.StorageVolume getPrimaryStorageVolume();
+    method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
     method public boolean isEncrypted(java.io.File);
     method public boolean isObbMounted(java.lang.String);
     method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
@@ -32207,6 +32210,9 @@
     method public android.content.SharedPreferences getSharedPreferences();
     method public int getSharedPreferencesMode();
     method public java.lang.String getSharedPreferencesName();
+    method public boolean isStorageCredentialProtected();
+    method public boolean isStorageDefault();
+    method public boolean isStorageDeviceProtected();
     method public static void setDefaultValues(android.content.Context, int, boolean);
     method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
     method public void setSharedPreferencesMode(int);
@@ -32583,7 +32589,7 @@
     method public android.print.PrinterInfo build();
     method public android.print.PrinterInfo.Builder setCapabilities(android.print.PrinterCapabilitiesInfo);
     method public android.print.PrinterInfo.Builder setDescription(java.lang.String);
-    method public android.print.PrinterInfo.Builder setHasCustomPrinterIcon();
+    method public android.print.PrinterInfo.Builder setHasCustomPrinterIcon(boolean);
     method public android.print.PrinterInfo.Builder setIconResourceId(int);
     method public android.print.PrinterInfo.Builder setInfoIntent(android.app.PendingIntent);
     method public android.print.PrinterInfo.Builder setName(java.lang.String);
@@ -32635,6 +32641,7 @@
     method public boolean isStarted();
     method public void setProgress(float);
     method public void setStatus(java.lang.CharSequence);
+    method public void setStatus(int);
     method public boolean setTag(java.lang.String);
     method public boolean start();
   }
@@ -32711,6 +32718,7 @@
   public class BlockedNumberContract {
     method public static boolean canCurrentUserBlockNumbers(android.content.Context);
     method public static boolean isBlocked(android.content.Context, java.lang.String);
+    method public static int unblock(android.content.Context, java.lang.String);
     field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
     field public static final android.net.Uri AUTHORITY_URI;
   }
@@ -34835,6 +34843,7 @@
     field public static final java.lang.String ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE = "android.settings.VOICE_CONTROL_BATTERY_SAVER_MODE";
     field public static final java.lang.String ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE = "android.settings.VOICE_CONTROL_DO_NOT_DISTURB_MODE";
     field public static final java.lang.String ACTION_VOICE_INPUT_SETTINGS = "android.settings.VOICE_INPUT_SETTINGS";
+    field public static final java.lang.String ACTION_VPN_SETTINGS = "android.settings.VPN_SETTINGS";
     field public static final java.lang.String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS";
@@ -37027,7 +37036,6 @@
     method public boolean onMenuOpened(int, android.view.Menu);
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
-    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -38571,9 +38579,11 @@
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
     method public void pullExternalCall();
+    method public final void putExtras(android.os.Bundle);
     method public void registerCallback(android.telecom.Call.Callback);
     method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
     method public void reject(boolean, java.lang.String);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public deprecated void removeListener(android.telecom.Call.Listener);
     method public void sendCallEvent(java.lang.String, android.os.Bundle);
     method public void splitFromConference();
@@ -38710,6 +38720,7 @@
     method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
     method public final deprecated long getConnectTimeMillis();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final long getConnectionTime();
     method public final java.util.List<android.telecom.Connection> getConnections();
     method public final android.telecom.DisconnectCause getDisconnectCause();
@@ -38724,6 +38735,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onConnectionAdded(android.telecom.Connection);
     method public void onDisconnect();
+    method public void onExtrasChanged(android.os.Bundle);
     method public void onHold();
     method public void onMerge(android.telecom.Connection);
     method public void onMerge();
@@ -38732,15 +38744,18 @@
     method public void onStopDtmfTone();
     method public void onSwap();
     method public void onUnhold();
+    method public final void putExtras(android.os.Bundle);
     method public final void removeConnection(android.telecom.Connection);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public final void setActive();
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final deprecated void setConnectTimeMillis(long);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionProperties(int);
     method public final void setConnectionTime(long);
     method public final void setDialing();
     method public final void setDisconnected(android.telecom.DisconnectCause);
-    method public final void setExtras(android.os.Bundle);
+    method public final deprecated void setExtras(android.os.Bundle);
     method public final void setOnHold();
     method public final void setStatusHints(android.telecom.StatusHints);
     method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
@@ -38767,6 +38782,7 @@
     method public final android.telecom.Conference getConference();
     method public final java.util.List<android.telecom.Conferenceable> getConferenceables();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
     method public final int getState();
@@ -38780,6 +38796,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onCallEvent(java.lang.String, android.os.Bundle);
     method public void onDisconnect();
+    method public void onExtrasChanged(android.os.Bundle);
     method public void onHold();
     method public void onPlayDtmfTone(char);
     method public void onPostDialContinue(boolean);
@@ -38790,6 +38807,9 @@
     method public void onStateChanged(int);
     method public void onStopDtmfTone();
     method public void onUnhold();
+    method public static java.lang.String propertiesToString(int);
+    method public final void putExtras(android.os.Bundle);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -38798,9 +38818,10 @@
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConferenceables(java.util.List<android.telecom.Conferenceable>);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionProperties(int);
     method public final void setDialing();
     method public final void setDisconnected(android.telecom.DisconnectCause);
-    method public final void setExtras(android.os.Bundle);
+    method public final deprecated void setExtras(android.os.Bundle);
     method public final void setInitialized();
     method public final void setInitializing();
     method public final void setNextPostDialChar(char);
@@ -38814,12 +38835,11 @@
     method public static java.lang.String stateToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
-    field public static final int CAPABILITY_CAN_PULL_CALL = 33554432; // 0x2000000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
-    field public static final int CAPABILITY_IS_EXTERNAL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
     field public static final int CAPABILITY_MERGE_CONFERENCE = 4; // 0x4
     field public static final int CAPABILITY_MUTE = 64; // 0x40
@@ -38837,6 +38857,7 @@
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
+    field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_DIALING = 3; // 0x3
     field public static final int STATE_DISCONNECTED = 6; // 0x6
@@ -39114,6 +39135,7 @@
     method public void disconnect();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final java.util.List<android.telecom.RemoteConnection> getConnections();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
@@ -39137,6 +39159,7 @@
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConference, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionAdded(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConference, int);
+    method public void onConnectionPropertiesChanged(android.telecom.RemoteConference, int);
     method public void onConnectionRemoved(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onDestroyed(android.telecom.RemoteConference);
     method public void onDisconnected(android.telecom.RemoteConference, android.telecom.DisconnectCause);
@@ -39155,6 +39178,7 @@
     method public android.telecom.RemoteConference getConference();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
     method public int getConnectionCapabilities();
+    method public int getConnectionProperties();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
     method public int getState();
@@ -39185,6 +39209,7 @@
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConnection, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConnection, int);
     method public void onConnectionEvent(android.telecom.RemoteConnection, java.lang.String, android.os.Bundle);
+    method public void onConnectionPropertiesChanged(android.telecom.RemoteConnection, int);
     method public void onDestroyed(android.telecom.RemoteConnection);
     method public void onDisconnected(android.telecom.RemoteConnection, android.telecom.DisconnectCause);
     method public void onExtrasChanged(android.telecom.RemoteConnection, android.os.Bundle);
@@ -44367,9 +44392,11 @@
   }
 
   public final class KeyboardShortcutInfo implements android.os.Parcelable {
+    ctor public KeyboardShortcutInfo(java.lang.CharSequence, int, int);
     ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
     method public int describeContents();
     method public char getBaseCharacter();
+    method public int getKeycode();
     method public java.lang.CharSequence getLabel();
     method public int getModifiers();
     method public void writeToParcel(android.os.Parcel, int);
@@ -46381,7 +46408,7 @@
     method public abstract boolean onMenuOpened(int, android.view.Menu);
     method public abstract void onPanelClosed(int, android.view.Menu);
     method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
-    method public default void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
+    method public default void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu, int);
     method public abstract boolean onSearchRequested();
     method public abstract boolean onSearchRequested(android.view.SearchEvent);
     method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -54179,41 +54206,11 @@
     method public java.io.File directory();
     method public java.lang.ProcessBuilder directory(java.io.File);
     method public java.util.Map<java.lang.String, java.lang.String> environment();
-    method public java.lang.ProcessBuilder inheritIO();
-    method public java.lang.ProcessBuilder redirectError(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectError(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectError();
     method public boolean redirectErrorStream();
     method public java.lang.ProcessBuilder redirectErrorStream(boolean);
-    method public java.lang.ProcessBuilder redirectInput(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectInput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectInput();
-    method public java.lang.ProcessBuilder redirectOutput(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectOutput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectOutput();
     method public java.lang.Process start() throws java.io.IOException;
   }
 
-  public static abstract class ProcessBuilder.Redirect {
-    method public static java.lang.ProcessBuilder.Redirect appendTo(java.io.File);
-    method public java.io.File file();
-    method public static java.lang.ProcessBuilder.Redirect from(java.io.File);
-    method public static java.lang.ProcessBuilder.Redirect to(java.io.File);
-    method public abstract java.lang.ProcessBuilder.Redirect.Type type();
-    field public static final java.lang.ProcessBuilder.Redirect INHERIT;
-    field public static final java.lang.ProcessBuilder.Redirect PIPE;
-  }
-
-  public static final class ProcessBuilder.Redirect.Type extends java.lang.Enum {
-    method public static java.lang.ProcessBuilder.Redirect.Type valueOf(java.lang.String);
-    method public static final java.lang.ProcessBuilder.Redirect.Type[] values();
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type APPEND;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type INHERIT;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type PIPE;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type READ;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type WRITE;
-  }
-
   public abstract interface Readable {
     method public abstract int read(java.nio.CharBuffer) throws java.io.IOException;
   }
@@ -60472,6 +60469,10 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
+    method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
+    method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
+    method public static void parallelSetAll(double[], java.util.function.IntToDoubleFunction);
     method public static void parallelSort(byte[]);
     method public static void parallelSort(byte[], int, int);
     method public static void parallelSort(char[]);
@@ -69486,4 +69487,3 @@
   }
 
 }
-
diff --git a/api/system-removed.txt b/api/system-removed.txt
index d48b9b3..bc17627 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -134,6 +134,15 @@
 
 }
 
+package android.os.storage {
+
+  public class StorageManager {
+    method public android.os.storage.StorageVolume getPrimaryVolume();
+    method public android.os.storage.StorageVolume[] getVolumeList();
+  }
+
+}
+
 package android.preference {
 
   public class PreferenceManager {
diff --git a/api/test-current.txt b/api/test-current.txt
index c1035af..941e6c6 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -301,13 +301,13 @@
     field public static final int backgroundTint = 16843883; // 0x101046b
     field public static final int backgroundTintMode = 16843884; // 0x101046c
     field public static final int backupAgent = 16843391; // 0x101027f
-    field public static final int backupInForeground = 16844059; // 0x101051b
+    field public static final int backupInForeground = 16844060; // 0x101051c
     field public static final int banner = 16843762; // 0x10103f2
     field public static final int baseline = 16843548; // 0x101031c
     field public static final int baselineAlignBottom = 16843042; // 0x1010122
     field public static final int baselineAligned = 16843046; // 0x1010126
     field public static final int baselineAlignedChildIndex = 16843047; // 0x1010127
-    field public static final int bitmap = 16844055; // 0x1010517
+    field public static final int bitmap = 16844056; // 0x1010518
     field public static final int borderlessButtonStyle = 16843563; // 0x101032b
     field public static final int bottom = 16843184; // 0x10101b0
     field public static final int bottomBright = 16842957; // 0x10100cd
@@ -326,7 +326,7 @@
     field public static final int buttonBarNeutralButtonStyle = 16843914; // 0x101048a
     field public static final int buttonBarPositiveButtonStyle = 16843913; // 0x1010489
     field public static final int buttonBarStyle = 16843566; // 0x101032e
-    field public static final int buttonGravity = 16844031; // 0x10104ff
+    field public static final int buttonGravity = 16844032; // 0x1010500
     field public static final int buttonStyle = 16842824; // 0x1010048
     field public static final int buttonStyleInset = 16842826; // 0x101004a
     field public static final int buttonStyleSmall = 16842825; // 0x1010049
@@ -337,9 +337,9 @@
     field public static final int calendarTextColor = 16843931; // 0x101049b
     field public static final int calendarViewShown = 16843596; // 0x101034c
     field public static final int calendarViewStyle = 16843613; // 0x101035d
-    field public static final int canControlMagnification = 16844040; // 0x1010508
-    field public static final int canPerformGestures = 16844046; // 0x101050e
-    field public static final int canRecord = 16844061; // 0x101051d
+    field public static final int canControlMagnification = 16844041; // 0x1010509
+    field public static final int canPerformGestures = 16844047; // 0x101050f
+    field public static final int canRecord = 16844062; // 0x101051e
     field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
     field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
@@ -379,7 +379,7 @@
     field public static final int codes = 16843330; // 0x1010242
     field public static final int collapseColumns = 16843083; // 0x101014b
     field public static final int collapseContentDescription = 16843984; // 0x10104d0
-    field public static final int collapseIcon = 16844032; // 0x1010500
+    field public static final int collapseIcon = 16844033; // 0x1010501
     field public static final int color = 16843173; // 0x10101a5
     field public static final int colorAccent = 16843829; // 0x1010435
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
@@ -420,12 +420,12 @@
     field public static final int contentInsetRight = 16843862; // 0x1010456
     field public static final int contentInsetStart = 16843859; // 0x1010453
     field public static final int contextClickable = 16844007; // 0x10104e7
-    field public static final int contextPopupMenuStyle = 16844034; // 0x1010502
+    field public static final int contextPopupMenuStyle = 16844035; // 0x1010503
     field public static final int controlX1 = 16843772; // 0x10103fc
     field public static final int controlX2 = 16843774; // 0x10103fe
     field public static final int controlY1 = 16843773; // 0x10103fd
     field public static final int controlY2 = 16843775; // 0x10103ff
-    field public static final int countDown = 16844060; // 0x101051c
+    field public static final int countDown = 16844061; // 0x101051d
     field public static final int country = 16843962; // 0x10104ba
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
@@ -443,7 +443,7 @@
     field public static final deprecated int dayOfWeekTextAppearance = 16843925; // 0x1010495
     field public static final int debuggable = 16842767; // 0x101000f
     field public static final int defaultHeight = 16844021; // 0x10104f5
-    field public static final int defaultToDeviceProtectedStorage = 16844037; // 0x1010505
+    field public static final int defaultToDeviceProtectedStorage = 16844038; // 0x1010506
     field public static final int defaultValue = 16843245; // 0x10101ed
     field public static final int defaultWidth = 16844020; // 0x10104f4
     field public static final int delay = 16843212; // 0x10101cc
@@ -463,7 +463,7 @@
     field public static final int dialogTheme = 16843528; // 0x1010308
     field public static final int dialogTitle = 16843250; // 0x10101f2
     field public static final int digits = 16843110; // 0x1010166
-    field public static final int directBootAware = 16844038; // 0x1010506
+    field public static final int directBootAware = 16844039; // 0x1010507
     field public static final int direction = 16843217; // 0x10101d1
     field public static final deprecated int directionDescriptions = 16843681; // 0x10103a1
     field public static final int directionPriority = 16843218; // 0x10101d2
@@ -514,8 +514,8 @@
     field public static final int enabled = 16842766; // 0x101000e
     field public static final int end = 16843996; // 0x10104dc
     field public static final int endColor = 16843166; // 0x101019e
-    field public static final int endX = 16844051; // 0x1010513
-    field public static final int endY = 16844052; // 0x1010514
+    field public static final int endX = 16844052; // 0x1010514
+    field public static final int endY = 16844053; // 0x1010515
     field public static final deprecated int endYear = 16843133; // 0x101017d
     field public static final int enterFadeDuration = 16843532; // 0x101030c
     field public static final int entries = 16842930; // 0x10100b2
@@ -535,7 +535,7 @@
     field public static final int expandableListViewStyle = 16842863; // 0x101006f
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
-    field public static final int externalService = 16844047; // 0x101050f
+    field public static final int externalService = 16844048; // 0x1010510
     field public static final int extraTension = 16843371; // 0x101026b
     field public static final int extractNativeLibs = 16844010; // 0x10104ea
     field public static final int factor = 16843219; // 0x10101d3
@@ -560,7 +560,7 @@
     field public static final int fillBefore = 16843196; // 0x10101bc
     field public static final int fillColor = 16843780; // 0x1010404
     field public static final int fillEnabled = 16843343; // 0x101024f
-    field public static final int fillType = 16844064; // 0x1010520
+    field public static final int fillType = 16844065; // 0x1010521
     field public static final int fillViewport = 16843130; // 0x101017a
     field public static final int filter = 16843035; // 0x101011b
     field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4
@@ -652,8 +652,8 @@
     field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
     field public static final int horizontalSpacing = 16843028; // 0x1010114
     field public static final int host = 16842792; // 0x1010028
-    field public static final int hotSpotX = 16844056; // 0x1010518
-    field public static final int hotSpotY = 16844057; // 0x1010519
+    field public static final int hotSpotX = 16844057; // 0x1010519
+    field public static final int hotSpotY = 16844058; // 0x101051a
     field public static final int hyphenationFrequency = 16843998; // 0x10104de
     field public static final int icon = 16842754; // 0x1010002
     field public static final int iconPreview = 16843337; // 0x1010249
@@ -740,7 +740,7 @@
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
     field public static final int labelTextSize = 16843317; // 0x1010235
-    field public static final int languageTag = 16844041; // 0x1010509
+    field public static final int languageTag = 16844042; // 0x101050a
     field public static final int largeHeap = 16843610; // 0x101035a
     field public static final int largeScreens = 16843398; // 0x1010286
     field public static final int largestWidthLimitDp = 16843622; // 0x1010366
@@ -798,7 +798,7 @@
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
     field public static final int letterSpacing = 16843958; // 0x10104b6
-    field public static final int level = 16844033; // 0x1010501
+    field public static final int level = 16844034; // 0x1010502
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
     field public static final int lines = 16843092; // 0x1010154
@@ -831,7 +831,7 @@
     field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
     field public static final int matchOrder = 16843855; // 0x101044f
     field public static final int max = 16843062; // 0x1010136
-    field public static final int maxButtonHeight = 16844030; // 0x10104fe
+    field public static final int maxButtonHeight = 16844031; // 0x10104ff
     field public static final int maxDate = 16843584; // 0x1010340
     field public static final int maxEms = 16843095; // 0x1010157
     field public static final int maxHeight = 16843040; // 0x1010120
@@ -859,7 +859,8 @@
     field public static final int minResizeWidth = 16843669; // 0x1010395
     field public static final int minSdkVersion = 16843276; // 0x101020c
     field public static final int minWidth = 16843071; // 0x101013f
-    field public static final int minimalSize = 16844022; // 0x10104f6
+    field public static final int minimalHeight = 16844023; // 0x10104f7
+    field public static final int minimalWidth = 16844022; // 0x10104f6
     field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
     field public static final int minimumVerticalAngle = 16843902; // 0x101047e
     field public static final int mipMap = 16843725; // 0x10103cd
@@ -880,7 +881,7 @@
     field public static final int nextFocusLeft = 16842977; // 0x10100e1
     field public static final int nextFocusRight = 16842978; // 0x10100e2
     field public static final int nextFocusUp = 16842979; // 0x10100e3
-    field public static final int nfcAntennaPositionDrawable = 16844063; // 0x101051f
+    field public static final int nfcAntennaPositionDrawable = 16844064; // 0x1010520
     field public static final int noHistory = 16843309; // 0x101022d
     field public static final int normalScreens = 16843397; // 0x1010285
     field public static final int notificationTimeout = 16843651; // 0x1010383
@@ -892,7 +893,7 @@
     field public static final int numbersTextColor = 16843937; // 0x10104a1
     field public static final deprecated int numeric = 16843109; // 0x1010165
     field public static final int numericShortcut = 16843236; // 0x10101e4
-    field public static final int offset = 16844053; // 0x1010515
+    field public static final int offset = 16844054; // 0x1010516
     field public static final int onClick = 16843375; // 0x101026f
     field public static final int oneshot = 16843159; // 0x1010197
     field public static final int opacity = 16843550; // 0x101031e
@@ -939,13 +940,13 @@
     field public static final deprecated int phoneNumber = 16843111; // 0x1010167
     field public static final int pivotX = 16843189; // 0x10101b5
     field public static final int pivotY = 16843190; // 0x10101b6
-    field public static final int pointerShape = 16844042; // 0x101050a
+    field public static final int pointerShape = 16844043; // 0x101050b
     field public static final int popupAnimationStyle = 16843465; // 0x10102c9
     field public static final int popupBackground = 16843126; // 0x1010176
     field public static final int popupCharacters = 16843332; // 0x1010244
     field public static final int popupElevation = 16843916; // 0x101048c
-    field public static final int popupEnterTransition = 16844065; // 0x1010521
-    field public static final int popupExitTransition = 16844066; // 0x1010522
+    field public static final int popupEnterTransition = 16844066; // 0x1010522
+    field public static final int popupExitTransition = 16844067; // 0x1010523
     field public static final int popupKeyboard = 16843331; // 0x1010243
     field public static final int popupLayout = 16843323; // 0x101023b
     field public static final int popupMenuStyle = 16843520; // 0x1010300
@@ -954,7 +955,7 @@
     field public static final int port = 16842793; // 0x1010029
     field public static final int positiveButtonText = 16843253; // 0x10101f5
     field public static final int preferenceCategoryStyle = 16842892; // 0x101008c
-    field public static final int preferenceFragmentStyle = 16844039; // 0x1010507
+    field public static final int preferenceFragmentStyle = 16844040; // 0x1010508
     field public static final int preferenceInformationStyle = 16842893; // 0x101008d
     field public static final int preferenceLayoutChild = 16842900; // 0x1010094
     field public static final int preferenceScreenStyle = 16842891; // 0x101008b
@@ -1022,7 +1023,7 @@
     field public static final int resizeClip = 16843983; // 0x10104cf
     field public static final int resizeMode = 16843619; // 0x1010363
     field public static final int resizeable = 16843405; // 0x101028d
-    field public static final int resizeableActivity = 16844023; // 0x10104f7
+    field public static final int resizeableActivity = 16844024; // 0x10104f8
     field public static final int resource = 16842789; // 0x1010025
     field public static final int restoreAnyVersion = 16843450; // 0x10102ba
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
@@ -1142,8 +1143,8 @@
     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 int startX = 16844049; // 0x1010511
-    field public static final int startY = 16844050; // 0x1010512
+    field public static final int startX = 16844050; // 0x1010512
+    field public static final int startY = 16844051; // 0x1010513
     field public static final deprecated int startYear = 16843132; // 0x101017c
     field public static final int stateListAnimator = 16843848; // 0x1010448
     field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -1200,8 +1201,8 @@
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsAssist = 16844016; // 0x10104f0
     field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
-    field public static final int supportsLocalInteraction = 16844048; // 0x1010510
-    field public static final int supportsPictureInPicture = 16844024; // 0x10104f8
+    field public static final int supportsLocalInteraction = 16844049; // 0x1010511
+    field public static final int supportsPictureInPicture = 16844025; // 0x10104f9
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
     field public static final int supportsUploading = 16843419; // 0x101029b
@@ -1250,7 +1251,7 @@
     field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f
     field public static final int textAppearanceMedium = 16842817; // 0x1010041
     field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044
-    field public static final int textAppearancePopupMenuHeader = 16844035; // 0x1010503
+    field public static final int textAppearancePopupMenuHeader = 16844036; // 0x1010504
     field public static final int textAppearanceSearchResultSubtitle = 16843424; // 0x10102a0
     field public static final int textAppearanceSearchResultTitle = 16843425; // 0x10102a1
     field public static final int textAppearanceSmall = 16842818; // 0x1010042
@@ -1308,9 +1309,9 @@
     field public static final int thumbTint = 16843889; // 0x1010471
     field public static final int thumbTintMode = 16843890; // 0x1010472
     field public static final int thumbnail = 16843429; // 0x10102a5
-    field public static final int tickMark = 16844043; // 0x101050b
-    field public static final int tickMarkTint = 16844044; // 0x101050c
-    field public static final int tickMarkTintMode = 16844045; // 0x101050d
+    field public static final int tickMark = 16844044; // 0x101050c
+    field public static final int tickMarkTint = 16844045; // 0x101050d
+    field public static final int tickMarkTintMode = 16844046; // 0x101050e
     field public static final int tileMode = 16843265; // 0x1010201
     field public static final int tileModeX = 16843895; // 0x1010477
     field public static final int tileModeY = 16843896; // 0x1010478
@@ -1322,11 +1323,11 @@
     field public static final int tintMode = 16843771; // 0x10103fb
     field public static final int title = 16843233; // 0x10101e1
     field public static final int titleCondensed = 16843234; // 0x10101e2
-    field public static final int titleMargin = 16844025; // 0x10104f9
-    field public static final int titleMarginBottom = 16844029; // 0x10104fd
-    field public static final int titleMarginEnd = 16844027; // 0x10104fb
-    field public static final int titleMarginStart = 16844026; // 0x10104fa
-    field public static final int titleMarginTop = 16844028; // 0x10104fc
+    field public static final int titleMargin = 16844026; // 0x10104fa
+    field public static final int titleMarginBottom = 16844030; // 0x10104fe
+    field public static final int titleMarginEnd = 16844028; // 0x10104fc
+    field public static final int titleMarginStart = 16844027; // 0x10104fb
+    field public static final int titleMarginTop = 16844029; // 0x10104fd
     field public static final int titleTextAppearance = 16843822; // 0x101042e
     field public static final int titleTextColor = 16844003; // 0x10104e3
     field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -1365,7 +1366,7 @@
     field public static final int trimPathEnd = 16843785; // 0x1010409
     field public static final int trimPathOffset = 16843786; // 0x101040a
     field public static final int trimPathStart = 16843784; // 0x1010408
-    field public static final int tunerCount = 16844062; // 0x101051e
+    field public static final int tunerCount = 16844063; // 0x101051f
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -1373,7 +1374,7 @@
     field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
-    field public static final int use32bitAbi = 16844054; // 0x1010516
+    field public static final int use32bitAbi = 16844055; // 0x1010517
     field public static final int useDefaultMargins = 16843641; // 0x1010379
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
@@ -1385,7 +1386,7 @@
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
     field public static final int vendor = 16843751; // 0x10103e7
-    field public static final int version = 16844058; // 0x101051a
+    field public static final int version = 16844059; // 0x101051b
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -1429,7 +1430,7 @@
     field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b
     field public static final int windowAnimationStyle = 16842926; // 0x10100ae
     field public static final int windowBackground = 16842836; // 0x1010054
-    field public static final int windowBackgroundFallback = 16844036; // 0x1010504
+    field public static final int windowBackgroundFallback = 16844037; // 0x1010505
     field public static final int windowClipToOutline = 16843947; // 0x10104ab
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
     field public static final int windowContentOverlay = 16842841; // 0x1010059
@@ -4280,6 +4281,7 @@
 
   public class DownloadManager {
     method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean);
+    method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean, android.net.Uri, android.net.Uri);
     method public long enqueue(android.app.DownloadManager.Request);
     method public static java.lang.Long getMaxBytesOverMobile(android.content.Context);
     method public java.lang.String getMimeTypeForDownloadedFile(long);
@@ -9263,7 +9265,6 @@
     field public int documentLaunchMode;
     field public int flags;
     field public int launchMode;
-    field public android.content.pm.ActivityInfo.Layout layout;
     field public int maxRecents;
     field public java.lang.String parentActivityName;
     field public java.lang.String permission;
@@ -9274,14 +9275,16 @@
     field public java.lang.String taskAffinity;
     field public int theme;
     field public int uiOptions;
+    field public android.content.pm.ActivityInfo.WindowLayout windowLayout;
   }
 
-  public static final class ActivityInfo.Layout {
-    ctor public ActivityInfo.Layout(int, float, int, float, int, int);
+  public static final class ActivityInfo.WindowLayout {
+    ctor public ActivityInfo.WindowLayout(int, float, int, float, int, int, int);
     field public final int gravity;
     field public final int height;
     field public final float heightFraction;
-    field public final int minimalSize;
+    field public final int minimalHeight;
+    field public final int minimalWidth;
     field public final int width;
     field public final float widthFraction;
   }
@@ -22345,7 +22348,7 @@
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
-    method public void unsubscribe(java.lang.String, android.os.Bundle);
+    method public void unsubscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
     field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
   }
@@ -23118,6 +23121,7 @@
     method public abstract void onStartRecording(android.net.Uri);
     method public abstract void onStopRecording();
     method public abstract void onTune(android.net.Uri);
+    method public void onTune(android.net.Uri, android.os.Bundle);
   }
 
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
@@ -23167,6 +23171,7 @@
     method public void startRecording(android.net.Uri);
     method public void stopRecording();
     method public void tune(java.lang.String, android.net.Uri);
+    method public void tune(java.lang.String, android.net.Uri, android.os.Bundle);
   }
 
   public static abstract class TvRecordingClient.RecordingCallback {
@@ -29630,8 +29635,8 @@
 
   public class StorageManager {
     method public java.lang.String getMountedObbPath(java.lang.String);
-    method public android.os.storage.StorageVolume getPrimaryVolume();
-    method public android.os.storage.StorageVolume[] getVolumeList();
+    method public android.os.storage.StorageVolume getPrimaryStorageVolume();
+    method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
     method public boolean isEncrypted(java.io.File);
     method public boolean isObbMounted(java.lang.String);
     method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
@@ -29959,6 +29964,8 @@
     method public android.content.SharedPreferences getSharedPreferences();
     method public int getSharedPreferencesMode();
     method public java.lang.String getSharedPreferencesName();
+    method public boolean isStorageDefault();
+    method public boolean isStorageDeviceProtected();
     method public static void setDefaultValues(android.content.Context, int, boolean);
     method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
     method public void setSharedPreferencesMode(int);
@@ -30260,7 +30267,7 @@
     method public android.print.PrinterId getPrinterId();
     method public float getProgress();
     method public int getState();
-    method public java.lang.CharSequence getStatus();
+    method public java.lang.CharSequence getStatus(android.content.pm.PackageManager);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.print.PrintJobInfo> CREATOR;
     field public static final int STATE_BLOCKED = 4; // 0x4
@@ -30337,7 +30344,7 @@
     method public android.print.PrinterInfo build();
     method public android.print.PrinterInfo.Builder setCapabilities(android.print.PrinterCapabilitiesInfo);
     method public android.print.PrinterInfo.Builder setDescription(java.lang.String);
-    method public android.print.PrinterInfo.Builder setHasCustomPrinterIcon();
+    method public android.print.PrinterInfo.Builder setHasCustomPrinterIcon(boolean);
     method public android.print.PrinterInfo.Builder setIconResourceId(int);
     method public android.print.PrinterInfo.Builder setInfoIntent(android.app.PendingIntent);
     method public android.print.PrinterInfo.Builder setName(java.lang.String);
@@ -30389,6 +30396,7 @@
     method public boolean isStarted();
     method public void setProgress(float);
     method public void setStatus(java.lang.CharSequence);
+    method public void setStatus(int);
     method public boolean setTag(java.lang.String);
     method public boolean start();
   }
@@ -30465,6 +30473,7 @@
   public class BlockedNumberContract {
     method public static boolean canCurrentUserBlockNumbers(android.content.Context);
     method public static boolean isBlocked(android.content.Context, java.lang.String);
+    method public static int unblock(android.content.Context, java.lang.String);
     field public static final java.lang.String AUTHORITY = "com.android.blockednumber";
     field public static final android.net.Uri AUTHORITY_URI;
   }
@@ -32457,6 +32466,7 @@
     field public static final java.lang.String ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE = "android.settings.VOICE_CONTROL_BATTERY_SAVER_MODE";
     field public static final java.lang.String ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE = "android.settings.VOICE_CONTROL_DO_NOT_DISTURB_MODE";
     field public static final java.lang.String ACTION_VOICE_INPUT_SETTINGS = "android.settings.VOICE_INPUT_SETTINGS";
+    field public static final java.lang.String ACTION_VPN_SETTINGS = "android.settings.VPN_SETTINGS";
     field public static final java.lang.String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS";
     field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS";
@@ -34336,6 +34346,7 @@
 
   public class NetworkSecurityPolicy {
     method public static android.security.NetworkSecurityPolicy getInstance();
+    method public void handleTrustStorageUpdate();
     method public boolean isCleartextTrafficPermitted();
     method public boolean isCleartextTrafficPermitted(java.lang.String);
   }
@@ -34648,7 +34659,6 @@
     method public boolean onMenuOpened(int, android.view.Menu);
     method public void onPanelClosed(int, android.view.Menu);
     method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
-    method public void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -36079,9 +36089,11 @@
     method public void playDtmfTone(char);
     method public void postDialContinue(boolean);
     method public void pullExternalCall();
+    method public final void putExtras(android.os.Bundle);
     method public void registerCallback(android.telecom.Call.Callback);
     method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
     method public void reject(boolean, java.lang.String);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public void sendCallEvent(java.lang.String, android.os.Bundle);
     method public void splitFromConference();
     method public void stopDtmfTone();
@@ -36210,6 +36222,7 @@
     method public final android.telecom.CallAudioState getCallAudioState();
     method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final long getConnectionTime();
     method public final java.util.List<android.telecom.Connection> getConnections();
     method public final android.telecom.DisconnectCause getDisconnectCause();
@@ -36222,6 +36235,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onConnectionAdded(android.telecom.Connection);
     method public void onDisconnect();
+    method public void onExtrasChanged(android.os.Bundle);
     method public void onHold();
     method public void onMerge(android.telecom.Connection);
     method public void onMerge();
@@ -36230,14 +36244,17 @@
     method public void onStopDtmfTone();
     method public void onSwap();
     method public void onUnhold();
+    method public final void putExtras(android.os.Bundle);
     method public final void removeConnection(android.telecom.Connection);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public final void setActive();
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionProperties(int);
     method public final void setConnectionTime(long);
     method public final void setDialing();
     method public final void setDisconnected(android.telecom.DisconnectCause);
-    method public final void setExtras(android.os.Bundle);
+    method public final deprecated void setExtras(android.os.Bundle);
     method public final void setOnHold();
     method public final void setStatusHints(android.telecom.StatusHints);
     method public final void setVideoProvider(android.telecom.Connection, android.telecom.Connection.VideoProvider);
@@ -36263,6 +36280,7 @@
     method public final android.telecom.Conference getConference();
     method public final java.util.List<android.telecom.Conferenceable> getConferenceables();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
     method public final int getState();
@@ -36275,6 +36293,7 @@
     method public void onCallAudioStateChanged(android.telecom.CallAudioState);
     method public void onCallEvent(java.lang.String, android.os.Bundle);
     method public void onDisconnect();
+    method public void onExtrasChanged(android.os.Bundle);
     method public void onHold();
     method public void onPlayDtmfTone(char);
     method public void onPostDialContinue(boolean);
@@ -36285,6 +36304,9 @@
     method public void onStateChanged(int);
     method public void onStopDtmfTone();
     method public void onUnhold();
+    method public static java.lang.String propertiesToString(int);
+    method public final void putExtras(android.os.Bundle);
+    method public final void removeExtras(java.util.List<java.lang.String>);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -36293,9 +36315,10 @@
     method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
     method public final void setConferenceables(java.util.List<android.telecom.Conferenceable>);
     method public final void setConnectionCapabilities(int);
+    method public final void setConnectionProperties(int);
     method public final void setDialing();
     method public final void setDisconnected(android.telecom.DisconnectCause);
-    method public final void setExtras(android.os.Bundle);
+    method public final deprecated void setExtras(android.os.Bundle);
     method public final void setInitialized();
     method public final void setInitializing();
     method public final void setNextPostDialChar(char);
@@ -36309,12 +36332,11 @@
     method public static java.lang.String stateToString(int);
     field public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 8388608; // 0x800000
     field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000
-    field public static final int CAPABILITY_CAN_PULL_CALL = 33554432; // 0x2000000
+    field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000
     field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
     field public static final int CAPABILITY_HOLD = 1; // 0x1
-    field public static final int CAPABILITY_IS_EXTERNAL_CALL = 16777216; // 0x1000000
     field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80
     field public static final int CAPABILITY_MERGE_CONFERENCE = 4; // 0x4
     field public static final int CAPABILITY_MUTE = 64; // 0x40
@@ -36332,6 +36354,7 @@
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
+    field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_DIALING = 3; // 0x3
     field public static final int STATE_DISCONNECTED = 6; // 0x6
@@ -36554,6 +36577,7 @@
     method public void disconnect();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
     method public final int getConnectionCapabilities();
+    method public final int getConnectionProperties();
     method public final java.util.List<android.telecom.RemoteConnection> getConnections();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
@@ -36576,6 +36600,7 @@
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConference, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionAdded(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConference, int);
+    method public void onConnectionPropertiesChanged(android.telecom.RemoteConference, int);
     method public void onConnectionRemoved(android.telecom.RemoteConference, android.telecom.RemoteConnection);
     method public void onDestroyed(android.telecom.RemoteConference);
     method public void onDisconnected(android.telecom.RemoteConference, android.telecom.DisconnectCause);
@@ -36594,6 +36619,7 @@
     method public android.telecom.RemoteConference getConference();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
     method public int getConnectionCapabilities();
+    method public int getConnectionProperties();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public final android.os.Bundle getExtras();
     method public int getState();
@@ -36623,6 +36649,7 @@
     method public void onConferenceableConnectionsChanged(android.telecom.RemoteConnection, java.util.List<android.telecom.RemoteConnection>);
     method public void onConnectionCapabilitiesChanged(android.telecom.RemoteConnection, int);
     method public void onConnectionEvent(android.telecom.RemoteConnection, java.lang.String, android.os.Bundle);
+    method public void onConnectionPropertiesChanged(android.telecom.RemoteConnection, int);
     method public void onDestroyed(android.telecom.RemoteConnection);
     method public void onDisconnected(android.telecom.RemoteConnection, android.telecom.DisconnectCause);
     method public void onExtrasChanged(android.telecom.RemoteConnection, android.os.Bundle);
@@ -41714,9 +41741,11 @@
   }
 
   public final class KeyboardShortcutInfo implements android.os.Parcelable {
+    ctor public KeyboardShortcutInfo(java.lang.CharSequence, int, int);
     ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
     method public int describeContents();
     method public char getBaseCharacter();
+    method public int getKeycode();
     method public java.lang.CharSequence getLabel();
     method public int getModifiers();
     method public void writeToParcel(android.os.Parcel, int);
@@ -43727,7 +43756,7 @@
     method public abstract boolean onMenuOpened(int, android.view.Menu);
     method public abstract void onPanelClosed(int, android.view.Menu);
     method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
-    method public default void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu);
+    method public default void onProvideKeyboardShortcuts(java.util.List<android.view.KeyboardShortcutGroup>, android.view.Menu, int);
     method public abstract boolean onSearchRequested();
     method public abstract boolean onSearchRequested(android.view.SearchEvent);
     method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -51187,41 +51216,11 @@
     method public java.io.File directory();
     method public java.lang.ProcessBuilder directory(java.io.File);
     method public java.util.Map<java.lang.String, java.lang.String> environment();
-    method public java.lang.ProcessBuilder inheritIO();
-    method public java.lang.ProcessBuilder redirectError(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectError(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectError();
     method public boolean redirectErrorStream();
     method public java.lang.ProcessBuilder redirectErrorStream(boolean);
-    method public java.lang.ProcessBuilder redirectInput(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectInput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectInput();
-    method public java.lang.ProcessBuilder redirectOutput(java.lang.ProcessBuilder.Redirect);
-    method public java.lang.ProcessBuilder redirectOutput(java.io.File);
-    method public java.lang.ProcessBuilder.Redirect redirectOutput();
     method public java.lang.Process start() throws java.io.IOException;
   }
 
-  public static abstract class ProcessBuilder.Redirect {
-    method public static java.lang.ProcessBuilder.Redirect appendTo(java.io.File);
-    method public java.io.File file();
-    method public static java.lang.ProcessBuilder.Redirect from(java.io.File);
-    method public static java.lang.ProcessBuilder.Redirect to(java.io.File);
-    method public abstract java.lang.ProcessBuilder.Redirect.Type type();
-    field public static final java.lang.ProcessBuilder.Redirect INHERIT;
-    field public static final java.lang.ProcessBuilder.Redirect PIPE;
-  }
-
-  public static final class ProcessBuilder.Redirect.Type extends java.lang.Enum {
-    method public static java.lang.ProcessBuilder.Redirect.Type valueOf(java.lang.String);
-    method public static final java.lang.ProcessBuilder.Redirect.Type[] values();
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type APPEND;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type INHERIT;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type PIPE;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type READ;
-    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type WRITE;
-  }
-
   public abstract interface Readable {
     method public abstract int read(java.nio.CharBuffer) throws java.io.IOException;
   }
@@ -57480,6 +57479,10 @@
     method public static int hashCode(float[]);
     method public static int hashCode(double[]);
     method public static int hashCode(java.lang.Object[]);
+    method public static void parallelSetAll(T[], java.util.function.IntFunction<? extends T>);
+    method public static void parallelSetAll(int[], java.util.function.IntUnaryOperator);
+    method public static void parallelSetAll(long[], java.util.function.IntToLongFunction);
+    method public static void parallelSetAll(double[], java.util.function.IntToDoubleFunction);
     method public static void parallelSort(byte[]);
     method public static void parallelSort(byte[], int, int);
     method public static void parallelSort(char[]);
@@ -66494,4 +66497,3 @@
   }
 
 }
-
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 36c8ce5..86085c8 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -136,6 +136,15 @@
 
 }
 
+package android.os.storage {
+
+  public class StorageManager {
+    method public android.os.storage.StorageVolume getPrimaryVolume();
+    method public android.os.storage.StorageVolume[] getVolumeList();
+  }
+
+}
+
 package android.preference {
 
   public class PreferenceManager {
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 86734b1..221b2d3 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1141,7 +1141,7 @@
         int userId = Integer.parseInt(nextArgRequired());
         byte[] token = argToBytes(nextArgRequired());
         byte[] secret = argToBytes(nextArgRequired());
-        boolean success = mAm.unlockUser(userId, token, secret);
+        boolean success = mAm.unlockUser(userId, token, secret, null);
         if (success) {
             System.out.println("Success: user unlocked");
         } else {
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index ea53e59..c597ed2 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -68,14 +68,11 @@
 
 // ---------------------------------------------------------------------------
 
-BootAnimation::BootAnimation() : Thread(false), mZip(NULL), mClockEnabled(true) {
+BootAnimation::BootAnimation() : Thread(false), mClockEnabled(true) {
     mSession = new SurfaceComposerClient();
 }
 
 BootAnimation::~BootAnimation() {
-    if (mZip != NULL) {
-        delete mZip;
-    }
 }
 
 void BootAnimation::onFirstRef() {
@@ -288,19 +285,15 @@
 
     bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt);
 
-    ZipFileRO* zipFile = NULL;
-    if ((encryptedAnimation &&
-            (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
-            ((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) ||
-
-            ((access(OEM_BOOTANIMATION_FILE, R_OK) == 0) &&
-            ((zipFile = ZipFileRO::open(OEM_BOOTANIMATION_FILE)) != NULL)) ||
-
-            ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
-            ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) {
-        mZip = zipFile;
+    if (encryptedAnimation && (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0)) {
+        mZipFileName = SYSTEM_ENCRYPTED_BOOTANIMATION_FILE;
     }
-
+    else if (access(OEM_BOOTANIMATION_FILE, R_OK) == 0) {
+        mZipFileName = OEM_BOOTANIMATION_FILE;
+    }
+    else if (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) {
+        mZipFileName = SYSTEM_BOOTANIMATION_FILE;
+    }
     return NO_ERROR;
 }
 
@@ -309,7 +302,7 @@
     bool r;
     // We have no bootanimation file, so we use the stock android logo
     // animation.
-    if (mZip == NULL) {
+    if (mZipFileName.isEmpty()) {
         r = android();
     } else {
         r = movie();
@@ -429,16 +422,17 @@
     return true;
 }
 
-bool BootAnimation::readFile(const char* name, String8& outString)
+
+static bool readFile(ZipFileRO* zip, const char* name, String8& outString)
 {
-    ZipEntryRO entry = mZip->findEntryByName(name);
+    ZipEntryRO entry = zip->findEntryByName(name);
     ALOGE_IF(!entry, "couldn't find %s", name);
     if (!entry) {
         return false;
     }
 
-    FileMap* entryMap = mZip->createEntryFileMap(entry);
-    mZip->releaseEntry(entry);
+    FileMap* entryMap = zip->createEntryFileMap(entry);
+    zip->releaseEntry(entry);
     ALOGE_IF(!entryMap, "entryMap is null");
     if (!entryMap) {
         return false;
@@ -512,18 +506,18 @@
     glBindTexture(GL_TEXTURE_2D, 0);
 }
 
-bool BootAnimation::movie()
+bool BootAnimation::parseAnimationDesc(Animation& animation)
 {
     String8 desString;
 
-    if (!readFile("desc.txt", desString)) {
+    if (!readFile(animation.zip, "desc.txt", desString)) {
         return false;
     }
     char const* s = desString.string();
 
     // Create and initialize an AudioPlayer if we have an audio_conf.txt file
     String8 audioConf;
-    if (readFile("audio_conf.txt", audioConf)) {
+    if (readFile(animation.zip, "audio_conf.txt", audioConf)) {
         mAudioPlayer = new AudioPlayer;
         if (!mAudioPlayer->init(audioConf.string())) {
             ALOGE("mAudioPlayer.init failed");
@@ -531,8 +525,6 @@
         }
     }
 
-    Animation animation;
-
     // Parse the description file
     for (;;) {
         const char* endl = strstr(s, "\n");
@@ -564,6 +556,7 @@
             part.path = path;
             part.clockPosY = clockPosY;
             part.audioFile = NULL;
+            part.animation = NULL;
             if (!parseColor(color, part.backgroundColor)) {
                 ALOGE("> invalid color '#%s'", color);
                 part.backgroundColor[0] = 0.0f;
@@ -572,13 +565,29 @@
             }
             animation.parts.add(part);
         }
-
+        else if (strcmp(l, "$SYSTEM") == 0) {
+            // ALOGD("> SYSTEM");
+            Animation::Part part;
+            part.playUntilComplete = false;
+            part.count = 1;
+            part.pause = 0;
+            part.audioFile = NULL;
+            part.animation = loadAnimation(String8(SYSTEM_BOOTANIMATION_FILE));
+            if (part.animation != NULL)
+                animation.parts.add(part);
+        }
         s = ++endl;
     }
 
+    return true;
+}
+
+bool BootAnimation::preloadZip(Animation& animation)
+{
     // read all the data structures
     const size_t pcount = animation.parts.size();
     void *cookie = NULL;
+    ZipFileRO* mZip = animation.zip;
     if (!mZip->startIteration(&cookie)) {
         return false;
     }
@@ -624,6 +633,16 @@
 
     mZip->endIteration(cookie);
 
+    return true;
+}
+
+bool BootAnimation::movie()
+{
+
+    Animation* animation = loadAnimation(mZipFileName);
+    if (animation == NULL)
+        return false;
+
     // Blend required to draw time on top of animation frames.
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     glShadeModel(GL_FLAT);
@@ -645,6 +664,19 @@
         mClockEnabled = clockTextureInitialized;
     }
 
+    playAnimation(*animation);
+    releaseAnimation(animation);
+
+    if (clockTextureInitialized) {
+        glDeleteTextures(1, &mClock.name);
+    }
+
+    return false;
+}
+
+bool BootAnimation::playAnimation(const Animation& animation)
+{
+    const size_t pcount = animation.parts.size();
     const int xc = (mWidth - animation.width) / 2;
     const int yc = ((mHeight - animation.height) / 2);
     nsecs_t frameDuration = s2ns(1) / animation.fps;
@@ -657,6 +689,14 @@
         const size_t fcount = part.frames.size();
         glBindTexture(GL_TEXTURE_2D, 0);
 
+        // Handle animation package
+        if (part.animation != NULL) {
+            playAnimation(*part.animation);
+            if (exitPending())
+                break;
+            continue; //to next part
+        }
+
         for (int r=0 ; !part.count || r<part.count ; r++) {
             // Exit any non playuntil complete parts immediately
             if(exitPending() && !part.playUntilComplete)
@@ -744,14 +784,46 @@
             }
         }
     }
-
-    if (clockTextureInitialized) {
-        glDeleteTextures(1, &mClock.name);
-    }
-
-    return false;
+    return true;
 }
 
+void BootAnimation::releaseAnimation(Animation* animation) const
+{
+    for (Vector<Animation::Part>::iterator it = animation->parts.begin(),
+         e = animation->parts.end(); it != e; ++it) {
+        if (it->animation)
+            releaseAnimation(it->animation);
+    }
+    if (animation->zip)
+        delete animation->zip;
+    delete animation;
+}
+
+BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn)
+{
+    if (mLoadedFiles.indexOf(fn) >= 0) {
+        ALOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",
+            fn.string());
+        return NULL;
+    }
+    ZipFileRO *zip = ZipFileRO::open(fn);
+    if (zip == NULL) {
+        ALOGE("Failed to open animation zip \"%s\": %s",
+            fn.string(), strerror(errno));
+        return NULL;
+    }
+
+    Animation *animation =  new Animation;
+    animation->fileName = fn;
+    animation->zip = zip;
+    mLoadedFiles.add(animation->fileName);
+
+    parseAnimationDesc(*animation);
+    preloadZip(*animation);
+
+    mLoadedFiles.remove(fn);
+    return animation;
+}
 // ---------------------------------------------------------------------------
 
 }
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 83e2b38..d49e1ec 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -76,19 +76,27 @@
             bool playUntilComplete;
             float backgroundColor[3];
             FileMap* audioFile;
+            Animation* animation;
         };
         int fps;
         int width;
         int height;
         Vector<Part> parts;
+        String8 audioConf;
+        String8 fileName;
+        ZipFileRO* zip;
     };
 
     status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
     status_t initTexture(const Animation::Frame& frame);
     bool android();
-    bool readFile(const char* name, String8& outString);
     bool movie();
     void drawTime(const Texture& clockTex, const int yPos);
+    Animation* loadAnimation(const String8&);
+    bool playAnimation(const Animation&);
+    void releaseAnimation(Animation*) const;
+    bool parseAnimationDesc(Animation&);
+    bool preloadZip(Animation &animation);
 
     void checkExit();
 
@@ -104,8 +112,9 @@
     EGLDisplay  mSurface;
     sp<SurfaceControl> mFlingerSurfaceControl;
     sp<Surface> mFlingerSurface;
-    ZipFileRO   *mZip;
     bool        mClockEnabled;
+    String8     mZipFileName;
+    SortedVector<String8> mLoadedFiles;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index 32edd4d..77df151 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -29,8 +29,9 @@
  * This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate
  * values between those keyframes for a given animation. The class internal to the animation
  * package because it is an implementation detail of how Keyframes are stored and used.
+ * @hide
  */
-class KeyframeSet implements Keyframes {
+public class KeyframeSet implements Keyframes {
 
     int mNumKeyframes;
 
diff --git a/core/java/android/animation/Keyframes.java b/core/java/android/animation/Keyframes.java
index c149bed..e40a86c 100644
--- a/core/java/android/animation/Keyframes.java
+++ b/core/java/android/animation/Keyframes.java
@@ -20,8 +20,9 @@
 /**
  * This interface abstracts a collection of Keyframe objects and is called by
  * ValueAnimator to calculate values between those keyframes for a given animation.
+ * @hide
  */
-interface Keyframes extends Cloneable {
+public interface Keyframes extends Cloneable {
 
     /**
      * Sets the TypeEvaluator to be used when calculating animated values. This object
diff --git a/core/java/android/animation/PathKeyframes.java b/core/java/android/animation/PathKeyframes.java
index 8230ac5..50a490e 100644
--- a/core/java/android/animation/PathKeyframes.java
+++ b/core/java/android/animation/PathKeyframes.java
@@ -34,8 +34,9 @@
  * Typically, the returned type is a PointF, but the individual components can be extracted
  * as either an IntKeyframes or FloatKeyframes.
  * </p>
+ * @hide
  */
-class PathKeyframes implements Keyframes {
+public class PathKeyframes implements Keyframes {
     private static final int FRACTION_OFFSET = 0;
     private static final int X_OFFSET = 1;
     private static final int Y_OFFSET = 2;
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 663f297..c6a5152 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -967,7 +967,7 @@
         AnimationHandler animationHandler = AnimationHandler.getInstance();
         animationHandler.addAnimationFrameCallback(this, (long) (mStartDelay * sDurationScale));
 
-        if (mStartDelay == 0) {
+        if (mStartDelay == 0 || mSeekFraction >= 0) {
             // If there's no start delay, init the animation and notify start listeners right away
             // to be consistent with the previous behavior. Otherwise, postpone this until the first
             // frame after the start delay.
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index cc1d68e8..ee17e8a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -57,6 +57,7 @@
 import android.graphics.drawable.InsetDrawable;
 import android.graphics.drawable.LayerDrawable;
 import android.graphics.drawable.ShapeDrawable;
+import android.hardware.input.InputManager;
 import android.media.AudioManager;
 import android.media.session.MediaController;
 import android.net.Uri;
@@ -91,6 +92,8 @@
 import android.view.ContextThemeWrapper;
 import android.view.DragEvent;
 import android.view.DropPermissions;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
@@ -1679,10 +1682,16 @@
     }
 
     @Override
-    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
+    public void onProvideKeyboardShortcuts(
+            List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
         if (menu == null) {
           return;
         }
+        final InputDevice inputDevice = InputManager.getInstance().getInputDevice(deviceId);
+        if (inputDevice == null) {
+            return;
+        }
+        final KeyCharacterMap keyCharacterMap = inputDevice.getKeyCharacterMap();
         KeyboardShortcutGroup group = null;
         int menuSize = menu.size();
         for (int i = 0; i < menuSize; ++i) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2d33a2c..6380801 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Point;
@@ -1790,7 +1791,7 @@
 
         public int taskWidth;
         public int taskHeight;
-        public int screenOrientation;
+        public int screenOrientation = Configuration.ORIENTATION_UNDEFINED;
 
         public TaskThumbnailInfo() {
             // Do nothing
@@ -1807,7 +1808,16 @@
         public void reset() {
             taskWidth = 0;
             taskHeight = 0;
-            screenOrientation = 0;
+            screenOrientation = Configuration.ORIENTATION_UNDEFINED;
+        }
+
+        /**
+         * Copies from another ThumbnailInfo.
+         */
+        public void copyFrom(TaskThumbnailInfo o) {
+            taskWidth = o.taskWidth;
+            taskHeight = o.taskHeight;
+            screenOrientation = o.screenOrientation;
         }
 
         /** @hide */
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 7310d67..5116634 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -114,4 +114,15 @@
      *               values.
      */
     public abstract void notifyAppTransitionStarting(int reason);
+
+    /**
+     * Callback for window manager to let activity manager know that the app transition was
+     * cancelled.
+     */
+    public abstract void notifyAppTransitionCancelled();
+
+    /**
+     * Callback for window manager to let activity manager know that the app transition is finished.
+     */
+    public abstract void notifyAppTransitionFinished();
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index f5d7e7e..4bf48a3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -41,6 +41,7 @@
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
+import android.os.IProgressListener;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
@@ -2122,7 +2123,9 @@
             int userId = data.readInt();
             byte[] token = data.createByteArray();
             byte[] secret = data.createByteArray();
-            boolean result = unlockUser(userId, token, secret);
+            IProgressListener listener = IProgressListener.Stub
+                    .asInterface(data.readStrongBinder());
+            boolean result = unlockUser(userId, token, secret, listener);
             reply.writeNoException();
             reply.writeInt(result ? 1 : 0);
             return true;
@@ -5707,13 +5710,15 @@
         return result;
     }
 
-    public boolean unlockUser(int userId, byte[] token, byte[] secret) throws RemoteException {
+    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(userId);
         data.writeByteArray(token);
         data.writeByteArray(secret);
+        data.writeStrongInterface(listener);
         mRemote.transact(IActivityManager.UNLOCK_USER_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean result = reply.readInt() != 0;
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 167e6cb..2846798 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -154,6 +154,12 @@
     private static final String KEY_LAUNCH_STACK_ID = "android.activity.launchStackId";
 
     /**
+     * The task id the activity should be launched into.
+     * @hide
+     */
+    private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";
+
+    /**
      * Where the docked stack should be positioned.
      * @hide
      */
@@ -224,6 +230,7 @@
     private int mExitCoordinatorIndex;
     private PendingIntent mUsageTimeReport;
     private int mLaunchStackId = INVALID_STACK_ID;
+    private int mLaunchTaskId = -1;
     private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
     private AppTransitionAnimationSpec mAnimSpecs[];
 
@@ -766,6 +773,7 @@
                 break;
         }
         mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
+        mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
         mDockCreateMode = opts.getInt(KEY_DOCK_CREATE_MODE, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT);
         if (opts.containsKey(KEY_ANIM_SPECS)) {
             Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
@@ -927,6 +935,21 @@
         mLaunchStackId = launchStackId;
     }
 
+    /**
+     * Sets the task the activity will be launched in.
+     * @hide
+     */
+    public void setLaunchTaskId(int taskId) {
+        mLaunchTaskId = taskId;
+    }
+
+    /**
+     * @hide
+     */
+    public int getLaunchTaskId() {
+        return mLaunchTaskId;
+    }
+
     /** @hide */
     public int getDockCreateMode() {
         return mDockCreateMode;
@@ -1079,6 +1102,7 @@
                 break;
         }
         b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
+        b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
         b.putInt(KEY_DOCK_CREATE_MODE, mDockCreateMode);
         if (mAnimSpecs != null) {
             b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 5b7dae6..ed590e6 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -272,12 +272,17 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
             throws NameNotFoundException {
         try {
-            List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags).getList();
-            if (pi != null) {
-                return pi;
+            ParceledListSlice<PermissionInfo> parceledList =
+                    mPM.queryPermissionsByGroup(group, flags);
+            if (parceledList != null) {
+                List<PermissionInfo> pi = parceledList.getList();
+                if (pi != null) {
+                    return pi;
+                }
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -288,7 +293,7 @@
 
     @Override
     public PermissionGroupInfo getPermissionGroupInfo(String name,
-                                                      int flags) throws NameNotFoundException {
+            int flags) throws NameNotFoundException {
         try {
             PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
             if (pgi != null) {
@@ -302,9 +307,15 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
         try {
-            return mPM.getAllPermissionGroups(flags).getList();
+            ParceledListSlice<PermissionGroupInfo> parceledList =
+                    mPM.getAllPermissionGroups(flags);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -439,9 +450,15 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public FeatureInfo[] getSystemAvailableFeatures() {
         try {
-            final List<FeatureInfo> list = mPM.getSystemAvailableFeatures().getList();
+            ParceledListSlice<FeatureInfo> parceledList =
+                    mPM.getSystemAvailableFeatures();
+            if (parceledList == null) {
+                return new FeatureInfo[0];
+            }
+            final List<FeatureInfo> list = parceledList.getList();
             final FeatureInfo[] res = new FeatureInfo[list.size()];
             for (int i = 0; i < res.length; i++) {
                 res[i] = list.get(i);
@@ -636,10 +653,15 @@
 
     /** @hide */
     @Override
+    @SuppressWarnings("unchecked")
     public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
         try {
-            ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId);
-            return slice.getList();
+            ParceledListSlice<PackageInfo> parceledList =
+                    mPM.getInstalledPackages(flags, userId);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -651,9 +673,12 @@
             String[] permissions, int flags) {
         final int userId = mContext.getUserId();
         try {
-            ParceledListSlice<PackageInfo> slice = mPM.getPackagesHoldingPermissions(
-                    permissions, flags, userId);
-            return slice.getList();
+            ParceledListSlice<PackageInfo> parceledList =
+                    mPM.getPackagesHoldingPermissions(permissions, flags, userId);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -664,8 +689,12 @@
     public List<ApplicationInfo> getInstalledApplications(int flags) {
         final int userId = mContext.getUserId();
         try {
-            ParceledListSlice<ApplicationInfo> slice = mPM.getInstalledApplications(flags, userId);
-            return slice.getList();
+            ParceledListSlice<ApplicationInfo> parceledList =
+                    mPM.getInstalledApplications(flags, userId);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -770,20 +799,25 @@
 
     /** @hide Same as above but for a specific user */
     @Override
+    @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
-                                                   int flags, int userId) {
+            int flags, int userId) {
         try {
-            return mPM.queryIntentActivities(
-                intent,
-                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                flags,
-                userId).getList();
+            ParceledListSlice<ResolveInfo> parceledList =
+                    mPM.queryIntentActivities(intent,
+                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                            flags, userId);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryIntentActivityOptions(
         ComponentName caller, Intent[] specifics, Intent intent,
         int flags) {
@@ -807,10 +841,13 @@
         }
 
         try {
-            return mPM
-                    .queryIntentActivityOptions(caller, specifics, specificTypes, intent,
-                            intent.resolveTypeIfNeeded(resolver), flags, mContext.getUserId())
-                    .getList();
+            ParceledListSlice<ResolveInfo> parceledList =
+                    mPM.queryIntentActivityOptions(caller, specifics, specificTypes, intent,
+                    intent.resolveTypeIfNeeded(resolver), flags, mContext.getUserId());
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -820,13 +857,17 @@
      * @hide
      */
     @Override
+    @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
         try {
-            return mPM.queryIntentReceivers(
-                intent,
-                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                flags,
-                userId).getList();
+            ParceledListSlice<ResolveInfo> parceledList =
+                    mPM.queryIntentReceivers(intent,
+                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                            flags,  userId);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -851,13 +892,17 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
         try {
-            return mPM.queryIntentServices(
-                intent,
-                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                flags,
-                userId).getList();
+            ParceledListSlice<ResolveInfo> parceledList =
+                    mPM.queryIntentServices(intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    flags, userId);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -869,12 +914,18 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryIntentContentProvidersAsUser(
             Intent intent, int flags, int userId) {
         try {
-            return mPM.queryIntentContentProviders(intent,
-                    intent.resolveTypeIfNeeded(mContext.getContentResolver()), flags, userId)
-                    .getList();
+            ParceledListSlice<ResolveInfo> parceledList =
+                    mPM.queryIntentContentProviders(intent,
+                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                            flags, userId);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -901,12 +952,13 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<ProviderInfo> queryContentProviders(String processName,
-                                                    int uid, int flags) {
+            int uid, int flags) {
         try {
-            ParceledListSlice<ProviderInfo> slice
-                    = mPM.queryContentProviders(processName, uid, flags);
-            return slice != null ? slice.getList() : null;
+            ParceledListSlice<ProviderInfo> slice =
+                    mPM.queryContentProviders(processName, uid, flags);
+            return slice != null ? slice.getList() : Collections.<ProviderInfo>emptyList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -930,10 +982,16 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<InstrumentationInfo> queryInstrumentation(
         String targetPackage, int flags) {
         try {
-            return mPM.queryInstrumentation(targetPackage, flags).getList();
+            ParceledListSlice<InstrumentationInfo> parceledList =
+                    mPM.queryInstrumentation(targetPackage, flags);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1575,18 +1633,30 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
         try {
-            return mPM.getIntentFilterVerifications(packageName).getList();
+            ParceledListSlice<IntentFilterVerificationInfo> parceledList =
+                    mPM.getIntentFilterVerifications(packageName);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public List<IntentFilter> getAllIntentFilters(String packageName) {
         try {
-            return mPM.getAllIntentFilters(packageName).getList();
+            ParceledListSlice<IntentFilter> parceledList =
+                    mPM.getAllIntentFilters(packageName);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 63a6829..d28f1fb 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -803,7 +803,12 @@
     @Override
     public void startActivity(Intent intent, Bundle options) {
         warnIfCallingFromSystemProcess();
-        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+
+        // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
+        // generally not allowed, except if the caller specifies the task id the activity should
+        // be launched in.
+        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
+                && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
             throw new AndroidRuntimeException(
                     "Calling startActivity() from outside of an Activity "
                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 79461b4..0bb1097 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -1082,13 +1082,6 @@
     }
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
-    }
-
-    /**
      * @return The activity associated with this dialog, or null if there is no associated activity.
      */
     private ComponentName getAssociatedActivity() {
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 536c4a8..8bc1aa3 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1193,13 +1193,52 @@
             boolean isMediaScannerScannable, String mimeType, String path, long length,
             boolean showNotification) {
         return addCompletedDownload(title, description, isMediaScannerScannable, mimeType, path,
-                length, showNotification, false);
+                length, showNotification, false, null, null);
+    }
+
+    /**
+     * Adds a file to the downloads database system, so it could appear in Downloads App
+     * (and thus become eligible for management by the Downloads App).
+     * <p>
+     * It is helpful to make the file scannable by MediaScanner by setting the param
+     * isMediaScannerScannable to true. It makes the file visible in media managing
+     * applications such as Gallery App, which could be a useful purpose of using this API.
+     *
+     * @param title the title that would appear for this file in Downloads App.
+     * @param description the description that would appear for this file in Downloads App.
+     * @param isMediaScannerScannable true if the file is to be scanned by MediaScanner. Files
+     * scanned by MediaScanner appear in the applications used to view media (for example,
+     * Gallery app).
+     * @param mimeType mimetype of the file.
+     * @param path absolute pathname to the file. The file should be world-readable, so that it can
+     * be managed by the Downloads App and any other app that is used to read it (for example,
+     * Gallery app to display the file, if the file contents represent a video/image).
+     * @param length length of the downloaded file
+     * @param showNotification true if a notification is to be sent, false otherwise
+     * @param uri the original HTTP URI of the download
+     * @param referer the HTTP Referer for the download
+     * @return  an ID for the download entry added to the downloads app, unique across the system
+     * This ID is used to make future calls related to this download.
+     */
+    public long addCompletedDownload(String title, String description,
+            boolean isMediaScannerScannable, String mimeType, String path, long length,
+            boolean showNotification, Uri uri, Uri referer) {
+        return addCompletedDownload(title, description, isMediaScannerScannable, mimeType, path,
+                length, showNotification, false, uri, referer);
     }
 
     /** {@hide} */
     public long addCompletedDownload(String title, String description,
             boolean isMediaScannerScannable, String mimeType, String path, long length,
             boolean showNotification, boolean allowWrite) {
+        return addCompletedDownload(title, description, isMediaScannerScannable, mimeType, path,
+                length, showNotification, allowWrite, null, null);
+    }
+
+    /** {@hide} */
+    public long addCompletedDownload(String title, String description,
+            boolean isMediaScannerScannable, String mimeType, String path, long length,
+            boolean showNotification, boolean allowWrite, Uri uri, Uri referer) {
         // make sure the input args are non-null/non-zero
         validateArgumentIsNonEmpty("title", title);
         validateArgumentIsNonEmpty("description", description);
@@ -1210,10 +1249,18 @@
         }
 
         // if there is already an entry with the given path name in downloads.db, return its id
-        Request request = new Request(NON_DOWNLOADMANAGER_DOWNLOAD)
-                .setTitle(title)
+        Request request;
+        if (uri != null) {
+            request = new Request(uri);
+        } else {
+            request = new Request(NON_DOWNLOADMANAGER_DOWNLOAD);
+        }
+        request.setTitle(title)
                 .setDescription(description)
                 .setMimeType(mimeType);
+        if (referer != null) {
+            request.addRequestHeader("Referer", referer.toString());
+        }
         ContentValues values = request.toContentValues(null);
         values.put(Downloads.Impl.COLUMN_DESTINATION,
                 Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD);
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index ddd0ae9..d89c0e0 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -537,12 +537,10 @@
                 setTransitioningViewsVisiblity(View.INVISIBLE, false);
             }
             TransitionManager.beginDelayedTransition(decorView, transition);
-            if (startSharedElementTransition && !mSharedElementNames.isEmpty()) {
-                mSharedElements.get(0).invalidate();
-            }
             if (startEnterTransition) {
-                setTransitioningViewsVisiblity(View.VISIBLE, true);
+                setTransitioningViewsVisiblity(View.VISIBLE, false);
             }
+            decorView.invalidate();
         } else {
             transitionStarted();
         }
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index d54ffa0..ce017f6 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -268,7 +268,8 @@
         if (transition != null && decorView != null && mTransitioningViews != null) {
             setTransitioningViewsVisiblity(View.VISIBLE, false);
             TransitionManager.beginDelayedTransition(decorView, transition);
-            setTransitioningViewsVisiblity(View.INVISIBLE, true);
+            setTransitioningViewsVisiblity(View.INVISIBLE, false);
+            decorView.invalidate();
         } else {
             transitionStarted();
         }
@@ -367,7 +368,7 @@
             scheduleGhostVisibilityChange(View.VISIBLE);
             setGhostVisibility(View.VISIBLE);
             if (viewsTransition != null) {
-                setTransitioningViewsVisiblity(View.INVISIBLE, true);
+                setTransitioningViewsVisiblity(View.INVISIBLE, false);
             }
             decorView.invalidate();
         } else {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 6870bbf..f7a4557 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -1429,16 +1429,20 @@
         final Context context = getContext();
         final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
         if (version >= Build.VERSION_CODES.N) {
-            if (savedInstanceState != null) {
-                Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
-                if (p != null) {
-                    if (mChildFragmentManager == null) {
-                        instantiateChildFragmentManager();
-                    }
-                    mChildFragmentManager.restoreAllState(p, mChildNonConfig);
-                    mChildNonConfig = null;
-                    mChildFragmentManager.dispatchCreate();
+            restoreChildFragmentState(savedInstanceState, true);
+        }
+    }
+
+    void restoreChildFragmentState(@Nullable Bundle savedInstanceState, boolean provideNonConfig) {
+        if (savedInstanceState != null) {
+            Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
+            if (p != null) {
+                if (mChildFragmentManager == null) {
+                    instantiateChildFragmentManager();
                 }
+                mChildFragmentManager.restoreAllState(p, provideNonConfig ? mChildNonConfig : null);
+                mChildNonConfig = null;
+                mChildFragmentManager.dispatchCreate();
             }
         }
     }
@@ -1692,6 +1696,18 @@
      */
     public void onDetach() {
         mCalled = true;
+
+        // Destroy the child FragmentManager if we still have it here.
+        // We won't unless we're retaining our instance and if we do,
+        // our child FragmentManager instance state will have already been saved.
+        if (mChildFragmentManager != null) {
+            if (!mRetaining) {
+                throw new IllegalStateException("Child FragmentManager of " + this + " was not "
+                        + " destroyed and this fragment is not retaining instance");
+            }
+            mChildFragmentManager.dispatchDestroy();
+            mChildFragmentManager = null;
+        }
     }
 
     /**
@@ -2252,16 +2268,7 @@
         final Context context = getContext();
         final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
         if (version < Build.VERSION_CODES.N) {
-            if (savedInstanceState != null) {
-                Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
-                if (p != null) {
-                    if (mChildFragmentManager == null) {
-                        instantiateChildFragmentManager();
-                    }
-                    mChildFragmentManager.restoreAllState(p, null);
-                    mChildFragmentManager.dispatchCreate();
-                }
-            }
+            restoreChildFragmentState(savedInstanceState, false);
         }
     }
 
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 0631943..2852baf 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -941,6 +941,9 @@
 
                     if (!f.mRetaining) {
                         f.performCreate(f.mSavedFragmentState);
+                    } else {
+                        f.restoreChildFragmentState(f.mSavedFragmentState, true);
+                        f.mState = Fragment.CREATED;
                     }
                     f.mRetaining = false;
                     if (f.mFromLayout) {
@@ -1009,6 +1012,9 @@
                         f.mSavedFragmentState = null;
                     }
                 case Fragment.ACTIVITY_CREATED:
+                    if (newState > Fragment.ACTIVITY_CREATED) {
+                        f.mState = Fragment.STOPPED;
+                    }
                 case Fragment.STOPPED:
                     if (newState > Fragment.STOPPED) {
                         if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
@@ -1108,7 +1114,7 @@
                             if (!f.mRetaining) {
                                 f.performDestroy();
                             } else {
-                                f.mState = Fragment.INITIALIZING;
+                                f.mState = Fragment.CREATED;
                             }
 
                             f.mCalled = false;
@@ -1124,7 +1130,6 @@
                                     f.mHost = null;
                                     f.mParentFragment = null;
                                     f.mFragmentManager = null;
-                                    f.mChildFragmentManager = null;
                                 }
                             }
                         }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 639c207..417c0679 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -47,6 +47,7 @@
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.IInterface;
+import android.os.IProgressListener;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
@@ -461,7 +462,8 @@
     // Multi-user APIs
     public boolean switchUser(int userid) throws RemoteException;
     public boolean startUserInBackground(int userid) throws RemoteException;
-    public boolean unlockUser(int userid, byte[] token, byte[] secret) throws RemoteException;
+    public boolean unlockUser(int userid, byte[] token, byte[] secret, IProgressListener listener)
+            throws RemoteException;
     public int stopUser(int userid, boolean force, IStopUserCallback callback) throws RemoteException;
     public UserInfo getCurrentUser() throws RemoteException;
     public boolean isUserRunning(int userid, int flags) throws RemoteException;
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 6432558..fa67529 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -35,4 +35,9 @@
      * Called whenever the pinned stack is done animating a resize.
      */
     void onPinnedStackAnimationEnded();
+
+    /**
+     * Called when we launched an activity that we forced to be resizable.
+     */
+    void onActivityForcedResizable(String packageName, int taskId);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 57ab7a2..66e0ada 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2856,12 +2856,15 @@
             "com.google.android.c2dm.intent.RECEIVE";
 
     /**
-     * Broadcast Action: hook for permforming cleanup after a system update.
+     * Broadcast Action: This is broadcast once when the user is booting after a
+     * system update. It can be used to perform cleanup or upgrades after a
+     * system update.
+     * <p>
+     * This broadcast is sent after the {@link #ACTION_LOCKED_BOOT_COMPLETED}
+     * broadcast but before the {@link #ACTION_BOOT_COMPLETED} broadcast. It's
+     * only sent when the {@link Build#FINGERPRINT} has changed, and it's only
+     * sent to receivers in the system image.
      *
-     * The broadcast is sent when the system is booting, before the
-     * BOOT_COMPLETED broadcast.  It is only sent to receivers in the system
-     * image.  A receiver for this should do its work and then disable itself
-     * so that it does not get run again at the next boot.
      * @hide
      */
     public static final String ACTION_PRE_BOOT_COMPLETED =
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 5da3c86..0f4cbbb 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -767,7 +767,11 @@
      */
     public int lockTaskLaunchMode;
 
-    public Layout layout;
+    /**
+     * Information about desired position and size of activity on the display when
+     * it is first started.
+     */
+    public WindowLayout windowLayout;
 
     public ActivityInfo() {
     }
@@ -788,7 +792,7 @@
         parentActivityName = orig.parentActivityName;
         maxRecents = orig.maxRecents;
         lockTaskLaunchMode = orig.lockTaskLaunchMode;
-        layout = orig.layout;
+        windowLayout = orig.windowLayout;
         resizeMode = orig.resizeMode;
     }
 
@@ -886,10 +890,10 @@
             pw.println(prefix + "lockTaskLaunchMode="
                     + lockTaskLaunchModeToString(lockTaskLaunchMode));
         }
-        if (layout != null) {
-            pw.println(prefix + "defaultLayout=" + layout.width + "|"
-                    + layout.widthFraction + ", " + layout.height + "|"
-                    + layout.heightFraction + ", " + layout.gravity);
+        if (windowLayout != null) {
+            pw.println(prefix + "windowLayout=" + windowLayout.width + "|"
+                    + windowLayout.widthFraction + ", " + windowLayout.height + "|"
+                    + windowLayout.heightFraction + ", " + windowLayout.gravity);
         }
         pw.println(prefix + "resizeMode=" + resizeModeToString(resizeMode));
         super.dumpBack(pw, prefix, flags);
@@ -922,14 +926,15 @@
         dest.writeInt(persistableMode);
         dest.writeInt(maxRecents);
         dest.writeInt(lockTaskLaunchMode);
-        if (layout != null) {
+        if (windowLayout != null) {
             dest.writeInt(1);
-            dest.writeInt(layout.width);
-            dest.writeFloat(layout.widthFraction);
-            dest.writeInt(layout.height);
-            dest.writeFloat(layout.heightFraction);
-            dest.writeInt(layout.gravity);
-            dest.writeInt(layout.minimalSize);
+            dest.writeInt(windowLayout.width);
+            dest.writeFloat(windowLayout.widthFraction);
+            dest.writeInt(windowLayout.height);
+            dest.writeFloat(windowLayout.heightFraction);
+            dest.writeInt(windowLayout.gravity);
+            dest.writeInt(windowLayout.minimalWidth);
+            dest.writeInt(windowLayout.minimalHeight);
         } else {
             dest.writeInt(0);
         }
@@ -964,36 +969,107 @@
         maxRecents = source.readInt();
         lockTaskLaunchMode = source.readInt();
         if (source.readInt() == 1) {
-            layout = new Layout(source);
+            windowLayout = new WindowLayout(source);
         }
         resizeMode = source.readInt();
     }
 
-    public static final class Layout {
-        public Layout(int width, float widthFraction, int height, float heightFraction, int gravity,
-                int minimalSize) {
+    /**
+     * Contains information about position and size of the activity on the display.
+     *
+     * Used in freeform mode to set desired position when activity is first launched.
+     * It describes how big the activity wants to be in both width and height,
+     * the minimal allowed size, and the gravity to be applied.
+     *
+     * @attr ref android.R.styleable#AndroidManifestLayout_defaultWidth
+     * @attr ref android.R.styleable#AndroidManifestLayout_defaultHeight
+     * @attr ref android.R.styleable#AndroidManifestLayout_gravity
+     * @attr ref android.R.styleable#AndroidManifestLayout_minimalWidth
+     * @attr ref android.R.styleable#AndroidManifestLayout_minimalHeight
+     */
+    public static final class WindowLayout {
+        public WindowLayout(int width, float widthFraction, int height, float heightFraction, int gravity,
+                int minimalWidth, int minimalHeight) {
             this.width = width;
             this.widthFraction = widthFraction;
             this.height = height;
             this.heightFraction = heightFraction;
             this.gravity = gravity;
-            this.minimalSize = minimalSize;
+            this.minimalWidth = minimalWidth;
+            this.minimalHeight = minimalHeight;
         }
 
-        Layout(Parcel source) {
+        WindowLayout(Parcel source) {
             width = source.readInt();
             widthFraction = source.readFloat();
             height = source.readInt();
             heightFraction = source.readFloat();
             gravity = source.readInt();
-            minimalSize = source.readInt();
+            minimalWidth = source.readInt();
+            minimalHeight = source.readInt();
         }
 
+        /**
+         * Width of activity in pixels.
+         *
+         * @attr ref android.R.styleable#AndroidManifestLayout_defaultWidth
+         */
         public final int width;
+
+        /**
+         * Width of activity as a fraction of available display width.
+         * If both {@link #width} and this value are set this one will be preferred.
+         *
+         * @attr ref android.R.styleable#AndroidManifestLayout_defaultWidth
+         */
         public final float widthFraction;
+
+        /**
+         * Height of activity in pixels.
+         *
+         * @attr ref android.R.styleable#AndroidManifestLayout_defaultHeight
+         */
         public final int height;
+
+        /**
+         * Height of activity as a fraction of available display height.
+         * If both {@link #height} and this value are set this one will be preferred.
+         *
+         * @attr ref android.R.styleable#AndroidManifestLayout_defaultHeight
+         */
         public final float heightFraction;
+
+        /**
+         * Gravity of activity.
+         * Currently {@link android.view.Gravity#TOP}, {@link android.view.Gravity#BOTTOM},
+         * {@link android.view.Gravity#LEFT} and {@link android.view.Gravity#RIGHT} are supported.
+         *
+         * @attr ref android.R.styleable#AndroidManifestLayout_gravity
+         */
         public final int gravity;
-        public final int minimalSize;
+
+        /**
+         * Minimal width of activity in pixels to be able to display its content.
+         *
+         * <p><strong>NOTE:</strong> A task's root activity value is applied to all additional
+         * activities launched in the task. That is if the root activity of a task set minimal
+         * width, then the system will set the same minimal width on all other activities in the
+         * task. It will also ignore any other minimal width attributes of non-root activities.
+         *
+         * @attr ref android.R.styleable#AndroidManifestLayout_minimalWidth
+         */
+        public final int minimalWidth;
+
+        /**
+         * Minimal height of activity in pixels to be able to display its content.
+         *
+         * <p><strong>NOTE:</strong> A task's root activity value is applied to all additional
+         * activities launched in the task. That is if the root activity of a task set minimal
+         * height, then the system will set the same minimal height on all other activities in the
+         * task. It will also ignore any other minimal height attributes of non-root activities.
+         *
+         * @attr ref android.R.styleable#AndroidManifestLayout_minimalHeight
+         */
+        public final int minimalHeight;
     }
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index dabc652..e3fb161 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -454,8 +454,21 @@
      */
     boolean performDexOptIfNeeded(String packageName, String instructionSet);
 
-    boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
-            boolean extractOnly, boolean force);
+    /**
+     * Ask the package manager to perform a dex-opt for the given reason. The package
+     * manager will map the reason to a compiler filter according to the current system
+     * configuration.
+     */
+    boolean performDexOpt(String packageName, String instructionSet, boolean checkProfiles,
+            int compileReason, boolean force);
+    /**
+     * Ask the package manager to perform a dex-opt with the given compiler filter.
+     *
+     * Note: exposed only for the shell command to allow moving packages explicitly to a
+     *       definite state.
+     */
+    boolean performDexOptMode(String packageName, String instructionSet, boolean checkProfiles,
+            String targetCompilerFilter, boolean force);
 
     void forceDexOpt(String packageName);
 
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index db7ca2af..ea251f6 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1158,10 +1158,15 @@
         StrictJarFile jarFile = null;
         try {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
+            // Ignore signature stripping protections when verifying APKs from system partition.
+            // For those APKs we only care about extracting signer certificates, and don't care
+            // about verifying integrity.
+            boolean signatureSchemeRollbackProtectionsEnforced =
+                    (parseFlags & PARSE_IS_SYSTEM) == 0;
             jarFile = new StrictJarFile(
                     apkPath,
-                    !verified // whether to verify JAR signature
-                    );
+                    !verified, // whether to verify JAR signature
+                    signatureSchemeRollbackProtectionsEnforced);
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
             // Always verify manifest, regardless of source
@@ -3643,12 +3648,15 @@
         int gravity = sw.getInt(
                 com.android.internal.R.styleable.AndroidManifestLayout_gravity,
                 Gravity.CENTER);
-        int minimalSize = sw.getDimensionPixelSize(
-                com.android.internal.R.styleable.AndroidManifestLayout_minimalSize,
+        int minimalWidth = sw.getDimensionPixelSize(
+                com.android.internal.R.styleable.AndroidManifestLayout_minimalWidth,
+                -1);
+        int minimalHeight = sw.getDimensionPixelSize(
+                com.android.internal.R.styleable.AndroidManifestLayout_minimalHeight,
                 -1);
         sw.recycle();
-        a.info.layout = new ActivityInfo.Layout(width, widthFraction,
-                height, heightFraction, gravity, minimalSize);
+        a.info.windowLayout = new ActivityInfo.WindowLayout(width, widthFraction,
+                height, heightFraction, gravity, minimalWidth, minimalHeight);
     }
 
     private Activity parseActivityAlias(Package owner, Resources res,
@@ -3730,7 +3738,7 @@
         info.uiOptions = target.info.uiOptions;
         info.parentActivityName = target.info.parentActivityName;
         info.maxRecents = target.info.maxRecents;
-        info.layout = target.info.layout;
+        info.windowLayout = target.info.windowLayout;
         info.resizeMode = target.info.resizeMode;
         info.encryptionAware = info.directBootAware = target.info.directBootAware;
 
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 3139151..dd3a36c 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -96,6 +96,7 @@
     public int flags;
     public long creationTime;
     public long lastLoggedInTime;
+    public String lastLoggedInFingerprint;
     public int profileGroupId;
     public int restrictedProfileParentId;
 
@@ -214,8 +215,10 @@
         serialNumber = orig.serialNumber;
         creationTime = orig.creationTime;
         lastLoggedInTime = orig.lastLoggedInTime;
+        lastLoggedInFingerprint = orig.lastLoggedInFingerprint;
         partial = orig.partial;
         profileGroupId = orig.profileGroupId;
+        restrictedProfileParentId = orig.restrictedProfileParentId;
         guestToRemove = orig.guestToRemove;
     }
 
@@ -240,6 +243,7 @@
         dest.writeInt(serialNumber);
         dest.writeLong(creationTime);
         dest.writeLong(lastLoggedInTime);
+        dest.writeString(lastLoggedInFingerprint);
         dest.writeInt(partial ? 1 : 0);
         dest.writeInt(profileGroupId);
         dest.writeInt(guestToRemove ? 1 : 0);
@@ -264,6 +268,7 @@
         serialNumber = source.readInt();
         creationTime = source.readLong();
         lastLoggedInTime = source.readLong();
+        lastLoggedInFingerprint = source.readString();
         partial = source.readInt() != 0;
         profileGroupId = source.readInt();
         guestToRemove = source.readInt() != 0;
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 9e360e1..20c2168 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -200,14 +200,6 @@
      */
     public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
 
-    /**
-     * Sent by ConnectivityService to the NetworkAgent to install an APF program in the network
-     * chipset for use to filter packets.
-     *
-     * obj = byte[] containing the APF program bytecode.
-     */
-    public static final int CMD_PUSH_APF_PROGRAM = BASE + 16;
-
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score) {
         this(looper, context, logTag, ni, nc, lp, score, null);
@@ -327,10 +319,6 @@
                 preventAutomaticReconnect();
                 break;
             }
-            case CMD_PUSH_APF_PROGRAM: {
-                installPacketFilter((byte[]) msg.obj);
-                break;
-            }
         }
     }
 
@@ -506,15 +494,6 @@
     protected void preventAutomaticReconnect() {
     }
 
-    /**
-     * Install a packet filter.
-     * @param filter an APF program to filter incoming packets.
-     * @return {@code true} if filter successfully installed, {@code false} otherwise.
-     */
-    protected boolean installPacketFilter(byte[] filter) {
-        return false;
-    }
-
     protected void log(String s) {
         Log.d(LOG_TAG, "NetworkAgent: " + s);
     }
diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java
index 748699e..5511a24 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -56,22 +56,6 @@
      */
     public String subscriberId;
 
-    /**
-     * Version of APF instruction set supported for packet filtering. 0 indicates no support for
-     * packet filtering using APF programs.
-     */
-    public int apfVersionSupported;
-
-    /**
-     * Maximum size of APF program allowed.
-     */
-    public int maximumApfProgramSize;
-
-    /**
-     * Format of packets passed to APF filter. Should be one of ARPHRD_*
-     */
-    public int apfPacketFormat;
-
     public NetworkMisc() {
     }
 
@@ -81,9 +65,6 @@
             explicitlySelected = nm.explicitlySelected;
             acceptUnvalidated = nm.acceptUnvalidated;
             subscriberId = nm.subscriberId;
-            apfVersionSupported = nm.apfVersionSupported;
-            maximumApfProgramSize = nm.maximumApfProgramSize;
-            apfPacketFormat = nm.apfPacketFormat;
         }
     }
 
@@ -98,9 +79,6 @@
         out.writeInt(explicitlySelected ? 1 : 0);
         out.writeInt(acceptUnvalidated ? 1 : 0);
         out.writeString(subscriberId);
-        out.writeInt(apfVersionSupported);
-        out.writeInt(maximumApfProgramSize);
-        out.writeInt(apfPacketFormat);
     }
 
     public static final Creator<NetworkMisc> CREATOR = new Creator<NetworkMisc>() {
@@ -111,9 +89,6 @@
             networkMisc.explicitlySelected = in.readInt() != 0;
             networkMisc.acceptUnvalidated = in.readInt() != 0;
             networkMisc.subscriberId = in.readString();
-            networkMisc.apfVersionSupported = in.readInt();
-            networkMisc.maximumApfProgramSize = in.readInt();
-            networkMisc.apfPacketFormat = in.readInt();
             return networkMisc;
         }
 
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index d847cd0..b32b2cc 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -18,6 +18,7 @@
 
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
+import static android.net.ConnectivityManager.TYPE_PROXY;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
@@ -68,6 +69,7 @@
     public static final int MATCH_MOBILE_WILDCARD = 6;
     public static final int MATCH_WIFI_WILDCARD = 7;
     public static final int MATCH_BLUETOOTH = 8;
+    public static final int MATCH_PROXY = 9;
 
     /**
      * Set of {@link NetworkInfo#getType()} that reflect data usage.
@@ -157,6 +159,14 @@
         return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
     }
 
+    /**
+     * Template to combine all {@link ConnectivityManager#TYPE_PROXY} style
+     * networks together.
+     */
+    public static NetworkTemplate buildTemplateProxy() {
+        return new NetworkTemplate(MATCH_PROXY, null, null);
+    }
+
     private final int mMatchRule;
     private final String mSubscriberId;
 
@@ -293,6 +303,8 @@
                 return matchesWifiWildcard(ident);
             case MATCH_BLUETOOTH:
                 return matchesBluetooth(ident);
+            case MATCH_PROXY:
+                return matchesProxy(ident);
             default:
                 throw new IllegalArgumentException("unknown network template");
         }
@@ -401,6 +413,13 @@
         return false;
     }
 
+    /**
+     * Check if matches Proxy network template.
+     */
+    private boolean matchesProxy(NetworkIdentity ident) {
+        return ident.mType == TYPE_PROXY;
+    }
+
     private static String getMatchRuleName(int matchRule) {
         switch (matchRule) {
             case MATCH_MOBILE_3G_LOWER:
@@ -419,6 +438,8 @@
                 return "WIFI_WILDCARD";
             case MATCH_BLUETOOTH:
                 return "BLUETOOTH";
+            case MATCH_PROXY:
+                return "PROXY";
             default:
                 return "UNKNOWN";
         }
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e730ad8..be82d56a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -30,6 +30,8 @@
 import android.telephony.SignalStrength;
 import android.text.format.DateFormat;
 import android.util.ArrayMap;
+import android.util.MutableBoolean;
+import android.util.Pair;
 import android.util.Printer;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
@@ -5317,26 +5319,28 @@
         }
 
         if (apps != null) {
-            SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
+            SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
             for (int i=0; i<apps.size(); i++) {
                 ApplicationInfo ai = apps.get(i);
-                ArrayList<String> pkgs = uids.get(ai.uid);
+                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(
+                        UserHandle.getAppId(ai.uid));
                 if (pkgs == null) {
-                    pkgs = new ArrayList<String>();
-                    uids.put(ai.uid, pkgs);
+                    pkgs = new Pair<>(new ArrayList<String>(), new MutableBoolean(false));
+                    uids.put(UserHandle.getAppId(ai.uid), pkgs);
                 }
-                pkgs.add(ai.packageName);
+                pkgs.first.add(ai.packageName);
             }
             SparseArray<? extends Uid> uidStats = getUidStats();
             final int NU = uidStats.size();
             String[] lineArgs = new String[2];
             for (int i=0; i<NU; i++) {
-                int uid = uidStats.keyAt(i);
-                ArrayList<String> pkgs = uids.get(uid);
-                if (pkgs != null) {
-                    for (int j=0; j<pkgs.size(); j++) {
+                int uid = UserHandle.getAppId(uidStats.keyAt(i));
+                Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(uid);
+                if (pkgs != null && !pkgs.second.value) {
+                    pkgs.second.value = true;
+                    for (int j=0; j<pkgs.first.size(); j++) {
                         lineArgs[0] = Integer.toString(uid);
-                        lineArgs[1] = pkgs.get(j);
+                        lineArgs[1] = pkgs.first.get(j);
                         dumpLine(pw, 0 /* uid */, "i" /* category */, UID_DATA,
                                 (Object[])lineArgs);
                     }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index de8b690..d0029e1 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -91,6 +91,12 @@
     /** The name of the hardware (from the kernel command line or /proc). */
     public static final String HARDWARE = getString("ro.hardware");
 
+    /**
+     * Whether this build was for an emulator device.
+     * @hide
+     */
+    public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");
+
     /** A hardware serial number, if available.  Alphanumeric only, case-insensitive. */
     public static final String SERIAL = getString("ro.serialno");
 
diff --git a/core/java/android/os/HardwarePropertiesManager.java b/core/java/android/os/HardwarePropertiesManager.java
index 0f2e33d..f13e5b5 100644
--- a/core/java/android/os/HardwarePropertiesManager.java
+++ b/core/java/android/os/HardwarePropertiesManager.java
@@ -101,7 +101,8 @@
      *         {@link #UNDEFINED_TEMPERATURE} if undefined.
      *         Empty if platform doesn't provide the queried temperature.
      *
-     * @throws SecurityException if a non profile or device owner tries to call this method.
+     * @throws SecurityException if something other than the profile or device owner, or the
+     *        current VR service tries to retrieve information provided by this service.
     */
     public @NonNull float[] getDeviceTemperatures(@DeviceTemperatureType int type,
             @TemperatureSource int source) {
@@ -137,7 +138,8 @@
      *         each unplugged core.
      *         Empty if CPU usage is not supported on this system.
      *
-     * @throws SecurityException if a non profile or device owner tries to call this method.
+     * @throws SecurityException if something other than the profile or device owner, or the
+     *        current VR service tries to retrieve information provided by this service.
      */
     public @NonNull CpuUsageInfo[] getCpuUsages() {
         try {
@@ -153,7 +155,8 @@
      * @return an array of float fan speeds in RPM. Empty if there are no fans or fan speed is not
      * supported on this system.
      *
-     * @throws SecurityException if a non profile or device owner tries to call this method.
+     * @throws SecurityException if something other than the profile or device owner, or the
+     *        current VR service tries to retrieve information provided by this service.
      */
     public @NonNull float[] getFanSpeeds() {
         try {
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 100f6a1..24a6cdf 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -293,7 +293,9 @@
     /**
      * Control network activity of a UID over interfaces with a quota limit.
      */
-    void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces);
+    void setUidMeteredNetworkBlacklist(int uid, boolean enable);
+    void setUidMeteredNetworkWhitelist(int uid, boolean enable);
+    boolean setDataSaverModeEnabled(boolean enable);
 
     void setUidCleartextNetworkPolicy(int uid, int policy);
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java b/core/java/android/os/IProgressListener.aidl
similarity index 66%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
copy to core/java/android/os/IProgressListener.aidl
index aaf77af..ad58a7c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
+++ b/core/java/android/os/IProgressListener.aidl
@@ -11,18 +11,16 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
 
-package com.android.systemui.recents.events.activity;
+package android.os;
 
-import com.android.systemui.recents.events.EventBus;
+import android.os.Bundle;
 
-/**
- * This is sent when the history view button is clicked.
- */
-public class ToggleHistoryEvent extends EventBus.AnimatedEvent {
-
-    // Simple event
-
+/** @hide */
+oneway interface IProgressListener {
+    void onStarted(int id, in Bundle extras);
+    void onProgress(int id, int progress, in Bundle extras);
+    void onFinished(int id, in Bundle extras);
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 22aec63..720d3f7 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -34,8 +34,8 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.provider.Settings;
-import android.security.KeyStore;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
@@ -49,6 +49,7 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -101,6 +102,10 @@
 
     /** {@hide} */
     public static final int FLAG_FOR_WRITE = 1 << 8;
+    /** {@hide} */
+    public static final int FLAG_REAL_STATE = 1 << 9;
+    /** {@hide} */
+    public static final int FLAG_INCLUDE_INVISIBLE = 1 << 10;
 
     private final Context mContext;
     private final ContentResolver mResolver;
@@ -859,11 +864,31 @@
     }
 
     /**
-     * Gets the list of shared/external storage volumes available to the current user.
+     * Return the list of shared/external storage volumes available to the
+     * current user. This includes both the primary shared storage device and
+     * any attached external volumes including SD cards and USB drives.
      *
-     * <p>It always contains the primary storage volume, plus any additional external volume(s)
-     * available in the device, such as SD cards or attached USB drives.
+     * @see Environment#getExternalStorageDirectory()
+     * @see StorageVolume#createAccessIntent(String)
      */
+    public @NonNull List<StorageVolume> getStorageVolumes() {
+        final ArrayList<StorageVolume> res = new ArrayList<>();
+        Collections.addAll(res,
+                getVolumeList(UserHandle.myUserId(), FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE));
+        return res;
+    }
+
+    /**
+     * Return the primary shared/external storage volume available to the
+     * current user. This volume is the same storage device returned by
+     * {@link Environment#getExternalStorageDirectory()} and
+     * {@link Context#getExternalFilesDir(String)}.
+     */
+    public @NonNull StorageVolume getPrimaryStorageVolume() {
+        return getVolumeList(UserHandle.myUserId(), FLAG_REAL_STATE | FLAG_INCLUDE_INVISIBLE)[0];
+    }
+
+    /** @removed */
     public @NonNull StorageVolume[] getVolumeList() {
         return getVolumeList(mContext.getUserId(), 0);
     }
@@ -912,9 +937,7 @@
         return paths;
     }
 
-    /**
-     * Gets the primary shared/external storage volume available to the current user.
-     */
+    /** @removed */
     public @NonNull StorageVolume getPrimaryVolume() {
         return getPrimaryVolume(getVolumeList());
     }
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index 17176ec..c028e15 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -16,7 +16,6 @@
 
 package android.os.storage;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
@@ -66,8 +65,8 @@
  * broad access to all files contained on a storage device.
  * </ul>
  *
- * <p>It can be obtained through {@link StorageManager#getVolumeList()} and
- * {@link StorageManager#getPrimaryVolume()} and also as an extra in some broadcasts
+ * <p>It can be obtained through {@link StorageManager#getStorageVolumes()} and
+ * {@link StorageManager#getPrimaryStorageVolume()} and also as an extra in some broadcasts
  * (see {@link #EXTRA_STORAGE_VOLUME}).
  *
  * <p>
@@ -336,7 +335,7 @@
      *
      * @see DocumentsContract
      */
-    public Intent createAccessIntent(@NonNull String directoryName) {
+    public Intent createAccessIntent(String directoryName) {
         final Intent intent = new Intent(ACTION_OPEN_EXTERNAL_DIRECTORY);
         intent.putExtra(EXTRA_STORAGE_VOLUME, this);
         intent.putExtra(EXTRA_DIRECTORY_NAME, directoryName);
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 47dc6c3..73174e3 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -412,6 +412,41 @@
     }
 
     /**
+     * Indicates if the storage location used internally by this class is the
+     * default provided by the hosting {@link Context}.
+     *
+     * @see #setStorageDefault()
+     * @see #setStorageDeviceProtected()
+     */
+    public boolean isStorageDefault() {
+        return mStorage == STORAGE_DEFAULT;
+    }
+
+    /**
+     * Indicates if the storage location used internally by this class is backed
+     * by device-protected storage.
+     *
+     * @see #setStorageDefault()
+     * @see #setStorageDeviceProtected()
+     */
+    public boolean isStorageDeviceProtected() {
+        return mStorage == STORAGE_DEVICE_PROTECTED;
+    }
+
+    /**
+     * Indicates if the storage location used internally by this class is backed
+     * by credential-protected storage.
+     *
+     * @see #setStorageDefault()
+     * @see #setStorageDeviceProtected()
+     * @hide
+     */
+    @SystemApi
+    public boolean isStorageCredentialProtected() {
+        return mStorage == STORAGE_CREDENTIAL_PROTECTED;
+    }
+
+    /**
      * Gets a SharedPreferences instance that preferences managed by this will
      * use.
      * 
diff --git a/core/java/android/print/IPrintSpooler.aidl b/core/java/android/print/IPrintSpooler.aidl
index 469a4ea..63bf885 100644
--- a/core/java/android/print/IPrintSpooler.aidl
+++ b/core/java/android/print/IPrintSpooler.aidl
@@ -61,6 +61,15 @@
     void setStatus(in PrintJobId printJobId, in CharSequence status);
 
     /**
+     * Set the status of this print job
+     *
+     * @param printJobId The print job to update
+     * @param status The new status as a string resource
+     * @param appPackageName App package name the resource belongs to
+     */
+    void setStatusRes(in PrintJobId printJobId, int status, in CharSequence appPackageName);
+
+    /**
      * Handle that a custom icon for a printer was loaded.
      *
      * @param printerId the id of the printer the icon belongs to
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
index 7e3a72f..f134943 100644
--- a/core/java/android/print/PrintJobInfo.java
+++ b/core/java/android/print/PrintJobInfo.java
@@ -21,7 +21,10 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.annotation.TestApi;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -181,7 +184,11 @@
     private float mProgress;
 
     /** A short string describing the status of this job. */
-    private CharSequence mStatus;
+    private @Nullable CharSequence mStatus;
+
+    /** A string resource describing the status of this job. */
+    private @StringRes int mStatusRes;
+    private @Nullable CharSequence mStatusResAppPackageName;
 
     /** Advanced printer specific options. */
     private Bundle mAdvancedOptions;
@@ -210,6 +217,8 @@
         mDocumentInfo = other.mDocumentInfo;
         mProgress = other.mProgress;
         mStatus = other.mStatus;
+        mStatusRes = other.mStatusRes;
+        mStatusResAppPackageName = other.mStatusResAppPackageName;
         mCanceling = other.mCanceling;
         mAdvancedOptions = other.mAdvancedOptions;
     }
@@ -235,8 +244,14 @@
         mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null);
         mProgress = parcel.readFloat();
         mStatus = parcel.readCharSequence();
+        mStatusRes = parcel.readInt();
+        mStatusResAppPackageName = parcel.readCharSequence();
         mCanceling = (parcel.readInt() == 1);
         mAdvancedOptions = parcel.readBundle();
+
+        if (mAdvancedOptions != null) {
+            Preconditions.checkArgument(!mAdvancedOptions.containsKey(null));
+        }
     }
 
     /**
@@ -370,10 +385,28 @@
      * @hide
      */
     public void setStatus(@Nullable CharSequence status) {
+        mStatusRes = 0;
+        mStatusResAppPackageName = null;
+
         mStatus = status;
     }
 
     /**
+     * Sets the status of the print job.
+     *
+     * @param status The new status as a string resource
+     * @param appPackageName App package name the resource belongs to
+     *
+     * @hide
+     */
+    public void setStatus(@StringRes int status, @NonNull CharSequence appPackageName) {
+        mStatus = null;
+
+        mStatusRes = status;
+        mStatusResAppPackageName = appPackageName;
+    }
+
+    /**
      * Sets the owning application id.
      *
      * @return The owning app id.
@@ -633,6 +666,8 @@
         parcel.writeParcelable(mDocumentInfo, 0);
         parcel.writeFloat(mProgress);
         parcel.writeCharSequence(mStatus);
+        parcel.writeInt(mStatusRes);
+        parcel.writeCharSequence(mStatusResAppPackageName);
         parcel.writeInt(mCanceling ? 1 : 0);
         parcel.writeBundle(mAdvancedOptions);
     }
@@ -659,6 +694,9 @@
         builder.append(", progress: " + mProgress);
         builder.append(", status: " + (mStatus != null
                 ? mStatus.toString() : null));
+        builder.append(", statusRes: " + mStatusRes);
+        builder.append(", statusResAppPackageName: " + (mStatusResAppPackageName != null
+                ? mStatusResAppPackageName.toString() : null));
         builder.append("}");
         return builder.toString();
     }
@@ -707,12 +745,23 @@
     /**
      * Get the status of this job.
      *
+     * @param pm Package manager used to resolve the string
+     *
      * @return the status of this job or null if not set
      * @hide
      */
     @TestApi
-    public @Nullable CharSequence getStatus() {
-        return mStatus;
+    public @Nullable CharSequence getStatus(@NonNull PackageManager pm) {
+        if (mStatusRes == 0) {
+            return mStatus;
+        } else {
+            try {
+                return pm.getResourcesForApplication(mStatusResAppPackageName.toString())
+                        .getString(mStatusRes);
+            } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
+                return null;
+            }
+        }
     }
 
     /**
@@ -789,6 +838,8 @@
          * @param value The option value.
          */
         public void putAdvancedOption(@NonNull String key, @Nullable String value) {
+            Preconditions.checkNotNull(key, "key cannot be null");
+
             if (mPrototype.mAdvancedOptions == null) {
                 mPrototype.mAdvancedOptions = new Bundle();
             }
diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java
index 0d2d9f4..1ee6389 100644
--- a/core/java/android/print/PrinterInfo.java
+++ b/core/java/android/print/PrinterInfo.java
@@ -467,10 +467,12 @@
          * {@link android.printservice.PrinterDiscoverySession#onRequestCustomPrinterIcon}.
          * </p>
          *
+         * @param hasCustomPrinterIcon If the printer has a custom icon or not.
+         *
          * @return This builder.
          */
-        public @NonNull Builder setHasCustomPrinterIcon() {
-            mHasCustomPrinterIcon = true;
+        public @NonNull Builder setHasCustomPrinterIcon(boolean hasCustomPrinterIcon) {
+            mHasCustomPrinterIcon = hasCustomPrinterIcon;
             return this;
         }
 
diff --git a/core/java/android/printservice/IPrintServiceClient.aidl b/core/java/android/printservice/IPrintServiceClient.aidl
index 0ae1e18..f0ea6ae 100644
--- a/core/java/android/printservice/IPrintServiceClient.aidl
+++ b/core/java/android/printservice/IPrintServiceClient.aidl
@@ -52,6 +52,15 @@
      */
     void setStatus(in PrintJobId printJobId, in CharSequence status);
 
+    /**
+     * Set the status of this print job
+     *
+     * @param printJobId The print job to update
+     * @param status The new status as a string resource
+     * @param appPackageName The app package name the string belongs to
+     */
+    void setStatusRes(in PrintJobId printJobId, int status, in CharSequence appPackageName);
+
     void onPrintersAdded(in ParceledListSlice printers);
     void onPrintersRemoved(in ParceledListSlice printerIds);
 
diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java
index 6414b6a..7a7ca23 100644
--- a/core/java/android/printservice/PrintJob.java
+++ b/core/java/android/printservice/PrintJob.java
@@ -20,11 +20,14 @@
 import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
+import android.content.Context;
 import android.os.RemoteException;
 import android.print.PrintJobId;
 import android.print.PrintJobInfo;
 import android.text.TextUtils;
 import android.util.Log;
+import com.android.internal.util.Preconditions;
 
 /**
  * This class represents a print job from the perspective of a print
@@ -45,7 +48,12 @@
 
     private PrintJobInfo mCachedInfo;
 
-    PrintJob(@NonNull PrintJobInfo jobInfo, @NonNull IPrintServiceClient client) {
+    /** Context that created the object */
+    private final Context mContext;
+
+    PrintJob(@NonNull Context context, @NonNull PrintJobInfo jobInfo,
+            @NonNull IPrintServiceClient client) {
+        mContext = context;
         mCachedInfo = jobInfo;
         mPrintServiceClient = client;
         mDocument = new PrintDocument(mCachedInfo.getId(), client,
@@ -216,11 +224,10 @@
     }
 
     /**
-     * Blocks the print job. You should call this method if {@link
-     * #isStarted()} or {@link #isBlocked()} returns true and you need
-     * to block the print job. For example, the user has to add some
-     * paper to continue printing. To resume the print job call {@link
-     * #start()}.
+     * Blocks the print job. You should call this method if {@link #isStarted()} returns true and
+     * you need to block the print job. For example, the user has to add some paper to continue
+     * printing. To resume the print job call {@link #start()}. To change the reason call
+     * {@link #setStatus(CharSequence)}.
      *
      * @param reason The human readable, short, and translated reason why the print job is blocked.
      * @return Whether the job was blocked.
@@ -233,9 +240,7 @@
         PrintService.throwIfNotCalledOnMainThread();
         PrintJobInfo info = getInfo();
         final int state = info.getState();
-        if (state == PrintJobInfo.STATE_STARTED
-                || (state == PrintJobInfo.STATE_BLOCKED
-                        && !TextUtils.equals(info.getStatus(), reason))) {
+        if (state == PrintJobInfo.STATE_STARTED || state == PrintJobInfo.STATE_BLOCKED) {
             return setState(PrintJobInfo.STATE_BLOCKED, reason);
         }
         return false;
@@ -320,6 +325,9 @@
     /**
      * Sets the status of this print job. This should be a human readable, short, and translated
      * description of the current state of the print job.
+     * <p />
+     * This overrides any previously set status set via {@link #setStatus(CharSequence)},
+     * {@link #setStatus(int)}, {@link #block(String)}, or {@link #fail(String)},
      *
      * @param status The new status. If null the status will be empty.
      */
@@ -335,6 +343,29 @@
     }
 
     /**
+     * Sets the status of this print job as a string resource.
+     * <p />
+     * This overrides any previously set status set via {@link #setStatus(CharSequence)},
+     * {@link #setStatus(int)}, {@link #block(String)}, or {@link #fail(String)},
+     * <p />
+     * To clear the status use {@link #setStatus(CharSequence) <code>setStatus(null)</code>}
+     *
+     * @param status  The new status as a String resource.
+     */
+    @MainThread
+    public void setStatus(@StringRes int status) {
+        PrintService.throwIfNotCalledOnMainThread();
+        Preconditions.checkArgument(status != 0, "status has to be != 0");
+
+        try {
+            mPrintServiceClient.setStatusRes(mCachedInfo.getId(), status,
+                    mContext.getPackageName());
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error setting status for job: " + mCachedInfo.getId(), re);
+        }
+    }
+
+    /**
      * Sets a tag that is valid in the context of a {@link PrintService}
      * and is not interpreted by the system. For example, a print service
      * may set as a tag the key of the print job returned by a remote
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index 62d214e..8f73518 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -329,7 +329,7 @@
                 final int printJobInfoCount = printJobInfos.size();
                 printJobs = new ArrayList<PrintJob>(printJobInfoCount);
                 for (int i = 0; i < printJobInfoCount; i++) {
-                    printJobs.add(new PrintJob(printJobInfos.get(i), mClient));
+                    printJobs.add(new PrintJob(this, printJobInfos.get(i), mClient));
                 }
             }
             if (printJobs != null) {
@@ -549,7 +549,7 @@
                                 + getPackageName());
                     }
                     PrintJobInfo printJobInfo = (PrintJobInfo) message.obj;
-                    onRequestCancelPrintJob(new PrintJob(printJobInfo, mClient));
+                    onRequestCancelPrintJob(new PrintJob(PrintService.this, printJobInfo, mClient));
                 } break;
 
                 case MSG_ON_PRINTJOB_QUEUED: {
@@ -561,7 +561,7 @@
                     if (DEBUG) {
                         Log.i(LOG_TAG, "Queued: " + printJobInfo);
                     }
-                    onPrintJobQueued(new PrintJob(printJobInfo, mClient));
+                    onPrintJobQueued(new PrintJob(PrintService.this, printJobInfo, mClient));
                 } break;
 
                 case MSG_SET_CLIENT: {
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
index 6fe0189..e90dc9c 100644
--- a/core/java/android/provider/BlockedNumberContract.java
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -15,6 +15,7 @@
  */
 package android.provider;
 
+import android.annotation.WorkerThread;
 import android.content.Context;
 import android.net.Uri;
 import android.os.Bundle;
@@ -109,6 +110,8 @@
  * Uri uri = getContentResolver().insert(BlockedNumbers.CONTENT_URI, values);
  * getContentResolver().delete(uri, null, null);
  * </pre>
+ * To check if a particular number is blocked, use the method
+ * {@link #isBlocked(Context, String)}.
  * </p>
  * </dd>
  * <dt><b>Query</b></dt>
@@ -120,8 +123,12 @@
  *          new String[]{BlockedNumbers.COLUMN_ID, BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
  *          BlockedNumbers.COLUMN_E164_NUMBER}, null, null, null);
  * </pre>
- * To check if a particular number is blocked, use the method
- * {@link #isBlocked(Context, String)}.
+ * </p>
+ * </dd>
+ * <dt><b>Unblock</b></dt>
+ * <dd>
+ * <p>
+ * Use the method {@link #unblock(Context, String)} to unblock numbers.
  * </p>
  * </dd>
  *
@@ -206,9 +213,15 @@
     public static final String METHOD_IS_BLOCKED = "is_blocked";
 
     /** @hide */
+    public static final String METHOD_UNBLOCK= "unblock";
+
+    /** @hide */
     public static final String RES_NUMBER_IS_BLOCKED = "blocked";
 
     /** @hide */
+    public static final String RES_NUM_ROWS_DELETED = "num_deleted";
+
+    /** @hide */
     public static final String METHOD_CAN_CURRENT_USER_BLOCK_NUMBERS =
             "can_current_user_block_numbers";
 
@@ -217,9 +230,15 @@
 
     /**
      * Returns whether a given number is in the blocked list.
+     *
+     * <p> This matches the {@code phoneNumber} against the
+     * {@link BlockedNumbers#COLUMN_ORIGINAL_NUMBER} column, and the E164 representation of the
+     * {@code phoneNumber} with the {@link BlockedNumbers#COLUMN_E164_NUMBER} column.
+     *
      * <p> Note that if the {@link #canCurrentUserBlockNumbers} is {@code false} for the user
      * context {@code context}, this method will throw an {@link UnsupportedOperationException}.
      */
+    @WorkerThread
     public static boolean isBlocked(Context context, String phoneNumber) {
         final Bundle res = context.getContentResolver().call(
                 AUTHORITY_URI, METHOD_IS_BLOCKED, phoneNumber, null);
@@ -227,6 +246,30 @@
     }
 
     /**
+     * Unblocks the {@code phoneNumber} if it is blocked.
+     *
+     * <p> Returns the number of rows deleted in the blocked number provider as a result of unblock.
+     *
+     * <p> This deletes all rows where the {@code phoneNumber} matches the
+     * {@link BlockedNumbers#COLUMN_ORIGINAL_NUMBER} column or the E164 representation of the
+     * {@code phoneNumber} matches the {@link BlockedNumbers#COLUMN_E164_NUMBER} column.
+     *
+     * <p>To delete rows based on exact match with specific columns such as
+     * {@link BlockedNumbers#COLUMN_ID} use
+     * {@link android.content.ContentProvider#delete(Uri, String, String[])} with
+     * {@link BlockedNumbers#CONTENT_URI} URI.
+     *
+     * <p> Note that if the {@link #canCurrentUserBlockNumbers} is {@code false} for the user
+     * context {@code context}, this method will throw an {@link UnsupportedOperationException}.
+     */
+    @WorkerThread
+    public static int unblock(Context context, String phoneNumber) {
+        final Bundle res = context.getContentResolver().call(
+                AUTHORITY_URI, METHOD_UNBLOCK, phoneNumber, null);
+        return res.getInt(RES_NUM_ROWS_DELETED, 0);
+    }
+
+    /**
      * Returns {@code true} if blocking numbers is supported for the current user.
      * <p> Typically, blocking numbers is only supported for one user at a time.
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d8937b4..f7e0e03 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -322,6 +322,20 @@
             "android.settings.PRIVACY_SETTINGS";
 
     /**
+     * Activity Action: Show settings to allow configuration of VPN.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_VPN_SETTINGS =
+            "android.settings.VPN_SETTINGS";
+
+    /**
      * Activity Action: Show settings to allow configuration of Wi-Fi.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -7699,6 +7713,16 @@
         public static final String DEVICE_IDLE_CONSTANTS = "device_idle_constants";
 
         /**
+         * Device Idle (Doze) specific settings for watches. See {@code #DEVICE_IDLE_CONSTANTS}
+         *
+         * <p>
+         * Type: string
+         * @hide
+         * @see com.android.server.DeviceIdleController.Constants
+         */
+        public static final String DEVICE_IDLE_CONSTANTS_WATCH = "device_idle_constants_watch";
+
+        /**
          * App standby (app idle) specific settings.
          * This is encoded as a key=value list, separated by commas. Ex:
          *
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
index 733a092..9530aca 100644
--- a/core/java/android/security/NetworkSecurityPolicy.java
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -16,6 +16,7 @@
 
 package android.security;
 
+import android.annotation.TestApi;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.security.net.config.ApplicationConfig;
@@ -104,4 +105,13 @@
         ManifestConfigSource source = new ManifestConfigSource(appContext);
         return new ApplicationConfig(source);
     }
+
+    /**
+     * Handle an update to the system or user certificate stores.
+     * @hide
+     */
+    @TestApi
+    public void handleTrustStorageUpdate() {
+        ApplicationConfig.getDefaultInstance().handleTrustStorageUpdate();
+    }
 }
diff --git a/core/java/android/security/net/config/ApplicationConfig.java b/core/java/android/security/net/config/ApplicationConfig.java
index 4de36cd..fadea56 100644
--- a/core/java/android/security/net/config/ApplicationConfig.java
+++ b/core/java/android/security/net/config/ApplicationConfig.java
@@ -17,6 +17,7 @@
 package android.security.net.config;
 
 import android.util.Pair;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Set;
 import javax.net.ssl.X509TrustManager;
@@ -146,6 +147,20 @@
         return getConfigForHostname(hostname).isCleartextTrafficPermitted();
     }
 
+    public void handleTrustStorageUpdate() {
+        ensureInitialized();
+        mDefaultConfig.handleTrustStorageUpdate();
+        if (mConfigs != null) {
+            Set<NetworkSecurityConfig> updatedConfigs =
+                    new HashSet<NetworkSecurityConfig>(mConfigs.size());
+            for (Pair<Domain, NetworkSecurityConfig> entry : mConfigs) {
+                if (updatedConfigs.add(entry.second)) {
+                    entry.second.handleTrustStorageUpdate();
+                }
+            }
+        }
+    }
+
     private void ensureInitialized() {
         synchronized(mLock) {
             if (mInitialized) {
diff --git a/core/java/android/security/net/config/CertificateSource.java b/core/java/android/security/net/config/CertificateSource.java
index f3272e4..4bcc405 100644
--- a/core/java/android/security/net/config/CertificateSource.java
+++ b/core/java/android/security/net/config/CertificateSource.java
@@ -25,4 +25,5 @@
     X509Certificate findBySubjectAndPublicKey(X509Certificate cert);
     X509Certificate findByIssuerAndSignature(X509Certificate cert);
     Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert);
+    void handleTrustStorageUpdate();
 }
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index 742d430..45cd0f0 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -64,4 +64,8 @@
     public Set<X509Certificate> findAllCertificatesByIssuerAndSignature(X509Certificate cert) {
         return mSource.findAllByIssuerAndSignature(cert);
     }
+
+    public void handleTrustStorageUpdate() {
+        mSource.handleTrustStorageUpdate();
+    }
 }
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index b2c068c..e3c9d65 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -126,6 +126,13 @@
         });
     }
 
+    @Override
+    public void handleTrustStorageUpdate() {
+        synchronized (mLock) {
+            mCertificates = null;
+        }
+    }
+
     private static interface CertSelector {
         boolean match(X509Certificate cert);
     }
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
index ba5dd83..c68f385 100644
--- a/core/java/android/security/net/config/KeyStoreCertificateSource.java
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -105,4 +105,9 @@
         }
         return certs;
     }
+
+    @Override
+    public void handleTrustStorageUpdate() {
+        // Nothing to do.
+    }
 }
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 6d6a92a..b3a37d0 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -117,12 +117,6 @@
         }
     }
 
-    void onTrustStoreChange() {
-        synchronized (mAnchorsLock) {
-            mAnchors = null;
-        }
-    }
-
     /** @hide */
     public TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) {
         for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
@@ -154,6 +148,16 @@
         return certs;
     }
 
+    public void handleTrustStorageUpdate() {
+        synchronized (mAnchorsLock) {
+            mAnchors = null;
+            for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
+                ref.handleTrustStorageUpdate();
+            }
+        }
+        getTrustManager().handleTrustStorageUpdate();
+    }
+
     /**
      * Return a {@link Builder} for the default {@code NetworkSecurityConfig}.
      *
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index 81cad79..f2c718cd 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -157,4 +157,11 @@
             return mIssuers.clone();
         }
     }
+
+    public void handleTrustStorageUpdate() {
+        synchronized (mIssuersLock) {
+            mIssuers = null;
+            mDelegate.handleTrustStorageUpdate();
+        }
+    }
 }
diff --git a/core/java/android/security/net/config/ResourceCertificateSource.java b/core/java/android/security/net/config/ResourceCertificateSource.java
index 22fbee2..78669c5 100644
--- a/core/java/android/security/net/config/ResourceCertificateSource.java
+++ b/core/java/android/security/net/config/ResourceCertificateSource.java
@@ -115,4 +115,9 @@
         }
         return certs;
     }
+
+    @Override
+    public void handleTrustStorageUpdate() {
+        // Nothing to do, resource sources never change.
+    }
 }
diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java
index d57d0f5..4a5f827 100644
--- a/core/java/android/security/net/config/XmlConfigSource.java
+++ b/core/java/android/security/net/config/XmlConfigSource.java
@@ -111,7 +111,7 @@
         if (parser.next() != XmlPullParser.TEXT) {
             throw new ParserException(parser, "Missing pin digest");
         }
-        String digest = parser.getText();
+        String digest = parser.getText().trim();
         byte[] decodedDigest = null;
         try {
             decodedDigest = Base64.decode(digest, 0);
@@ -168,7 +168,7 @@
         if (parser.next() != XmlPullParser.TEXT) {
             throw new ParserException(parser, "Domain name missing");
         }
-        String domain = parser.getText().toLowerCase(Locale.US);
+        String domain = parser.getText().trim().toLowerCase(Locale.US);
         if (parser.next() != XmlPullParser.END_TAG) {
             throw new ParserException(parser, "domain contains additional elements");
         }
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 816ecde..7af0b05 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -367,11 +367,6 @@
     @Override
     public void onActionModeFinished(ActionMode mode) {
     }
-
-    /** {@inheritDoc} */
-    @Override
-    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
-    }
     // end Window.Callback methods
 
     // begin public api
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 692d848..0bd5071 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -799,6 +799,31 @@
         return false;
     }
 
+    /**
+     * Returns the range of the run that the character at offset belongs to.
+     * @param offset the offset
+     * @return The range of the run
+     * @hide
+     */
+    public long getRunRange(int offset) {
+        int line = getLineForOffset(offset);
+        Directions dirs = getLineDirections(line);
+        if (dirs == DIRS_ALL_LEFT_TO_RIGHT || dirs == DIRS_ALL_RIGHT_TO_LEFT) {
+            return TextUtils.packRangeInLong(0, getLineEnd(line));
+        }
+        int[] runs = dirs.mDirections;
+        int lineStart = getLineStart(line);
+        for (int i = 0; i < runs.length; i += 2) {
+            int start = lineStart + runs[i];
+            int limit = start + (runs[i+1] & RUN_LENGTH_MASK);
+            if (offset >= start && offset < limit) {
+                return TextUtils.packRangeInLong(start, limit);
+            }
+        }
+        // Should happen only if the offset is "out of bounds"
+        return TextUtils.packRangeInLong(0, getLineEnd(line));
+    }
+
     private boolean primaryIsTrailingPrevious(int offset) {
         int line = getLineForOffset(offset);
         int lineStart = getLineStart(line);
@@ -886,6 +911,10 @@
         return getHorizontal(offset, !trailing, clamped);
     }
 
+    private float getHorizontal(int offset, boolean primary) {
+        return primary ? getPrimaryHorizontal(offset) : getSecondaryHorizontal(offset);
+    }
+
     private float getHorizontal(int offset, boolean trailing, boolean clamped) {
         int line = getLineForOffset(offset);
 
@@ -1114,6 +1143,20 @@
      * closest to the specified horizontal position.
      */
     public int getOffsetForHorizontal(int line, float horiz) {
+        return getOffsetForHorizontal(line, horiz, true);
+    }
+
+    /**
+     * Get the character offset on the specified line whose position is
+     * closest to the specified horizontal position.
+     *
+     * @param line the line used to find the closest offset
+     * @param horiz the horizontal position used to find the closest offset
+     * @param primary whether to use the primary position or secondary position to find the offset
+     *
+     * @hide
+     */
+    public int getOffsetForHorizontal(int line, float horiz, boolean primary) {
         // TODO: use Paint.getOffsetForAdvance to avoid binary search
         final int lineEndOffset = getLineEnd(line);
         final int lineStartOffset = getLineStart(line);
@@ -1133,7 +1176,7 @@
                     !isRtlCharAt(lineEndOffset - 1)) + lineStartOffset;
         }
         int best = lineStartOffset;
-        float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
+        float bestdist = Math.abs(getHorizontal(best, primary) - horiz);
 
         for (int i = 0; i < dirs.mDirections.length; i += 2) {
             int here = lineStartOffset + dirs.mDirections[i];
@@ -1149,7 +1192,7 @@
                 guess = (high + low) / 2;
                 int adguess = getOffsetAtStartOf(guess);
 
-                if (getPrimaryHorizontal(adguess) * swap >= horiz * swap)
+                if (getHorizontal(adguess, primary) * swap >= horiz * swap)
                     high = guess;
                 else
                     low = guess;
@@ -1162,9 +1205,9 @@
                 int aft = tl.getOffsetToLeftRightOf(low - lineStartOffset, isRtl) + lineStartOffset;
                 low = tl.getOffsetToLeftRightOf(aft - lineStartOffset, !isRtl) + lineStartOffset;
                 if (low >= here && low < there) {
-                    float dist = Math.abs(getPrimaryHorizontal(low) - horiz);
+                    float dist = Math.abs(getHorizontal(low, primary) - horiz);
                     if (aft < there) {
-                        float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
+                        float other = Math.abs(getHorizontal(aft, primary) - horiz);
 
                         if (other < dist) {
                             dist = other;
@@ -1179,7 +1222,7 @@
                 }
             }
 
-            float dist = Math.abs(getPrimaryHorizontal(here) - horiz);
+            float dist = Math.abs(getHorizontal(here, primary) - horiz);
 
             if (dist < bestdist) {
                 bestdist = dist;
@@ -1187,7 +1230,7 @@
             }
         }
 
-        float dist = Math.abs(getPrimaryHorizontal(max) - horiz);
+        float dist = Math.abs(getHorizontal(max, primary) - horiz);
 
         if (dist <= bestdist) {
             bestdist = dist;
diff --git a/core/java/android/util/jar/StrictJarFile.java b/core/java/android/util/jar/StrictJarFile.java
index 302a08d..5d94b06 100644
--- a/core/java/android/util/jar/StrictJarFile.java
+++ b/core/java/android/util/jar/StrictJarFile.java
@@ -58,11 +58,22 @@
 
     public StrictJarFile(String fileName)
             throws IOException, SecurityException {
-        this(fileName, true);
+        this(fileName, true, true);
     }
 
-    public StrictJarFile(String fileName, boolean verify)
-            throws IOException, SecurityException {
+    /**
+     *
+     * @param verify whether to verify the file's JAR signatures and collect the corresponding
+     *        signer certificates.
+     * @param signatureSchemeRollbackProtectionsEnforced {@code true} to enforce protections against
+     *        stripping newer signature schemes (e.g., APK Signature Scheme v2) from the file, or
+     *        {@code false} to ignore any such protections. This parameter is ignored when
+     *        {@code verify} is {@code false}.
+     */
+    public StrictJarFile(String fileName,
+            boolean verify,
+            boolean signatureSchemeRollbackProtectionsEnforced)
+                    throws IOException, SecurityException {
         this.nativeHandle = nativeOpenJarFile(fileName);
         this.raf = new RandomAccessFile(fileName, "r");
 
@@ -73,7 +84,12 @@
             if (verify) {
                 HashMap<String, byte[]> metaEntries = getMetaEntries();
                 this.manifest = new StrictJarManifest(metaEntries.get(JarFile.MANIFEST_NAME), true);
-                this.verifier = new StrictJarVerifier(fileName, manifest, metaEntries);
+                this.verifier =
+                        new StrictJarVerifier(
+                                fileName,
+                                manifest,
+                                metaEntries,
+                                signatureSchemeRollbackProtectionsEnforced);
                 Set<String> files = manifest.getEntries().keySet();
                 for (String file : files) {
                     if (findEntry(file) == null) {
diff --git a/core/java/android/util/jar/StrictJarVerifier.java b/core/java/android/util/jar/StrictJarVerifier.java
index 0546a5f..6da50ba 100644
--- a/core/java/android/util/jar/StrictJarVerifier.java
+++ b/core/java/android/util/jar/StrictJarVerifier.java
@@ -72,6 +72,7 @@
     private final StrictJarManifest manifest;
     private final HashMap<String, byte[]> metaEntries;
     private final int mainAttributesEnd;
+    private final boolean signatureSchemeRollbackProtectionsEnforced;
 
     private final Hashtable<String, HashMap<String, Attributes>> signatures =
             new Hashtable<String, HashMap<String, Attributes>>(5);
@@ -164,13 +165,19 @@
      *
      * @param name
      *            the name of the JAR file being verified.
+     *
+     * @param signatureSchemeRollbackProtectionsEnforced {@code true} to enforce protections against
+     *        stripping newer signature schemes (e.g., APK Signature Scheme v2) from the file, or
+     *        {@code false} to ignore any such protections.
      */
     StrictJarVerifier(String name, StrictJarManifest manifest,
-        HashMap<String, byte[]> metaEntries) {
+        HashMap<String, byte[]> metaEntries, boolean signatureSchemeRollbackProtectionsEnforced) {
         jarName = name;
         this.manifest = manifest;
         this.metaEntries = metaEntries;
         this.mainAttributesEnd = manifest.getMainAttributesEnd();
+        this.signatureSchemeRollbackProtectionsEnforced =
+                signatureSchemeRollbackProtectionsEnforced;
     }
 
     /**
@@ -357,40 +364,42 @@
             return;
         }
 
-        // Check whether APK Signature Scheme v2 signature was stripped.
-        String apkSignatureSchemeIdList =
-                attributes.getValue(
-                        ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME);
-        if (apkSignatureSchemeIdList != null) {
-            // This field contains a comma-separated list of APK signature scheme IDs which were
-            // used to sign this APK. If an ID is known to us, it means signatures of that scheme
-            // were stripped from the APK because otherwise we wouldn't have fallen back to
-            // verifying the APK using the JAR signature scheme.
-            boolean v2SignatureGenerated = false;
-            StringTokenizer tokenizer = new StringTokenizer(apkSignatureSchemeIdList, ",");
-            while (tokenizer.hasMoreTokens()) {
-                String idText = tokenizer.nextToken().trim();
-                if (idText.isEmpty()) {
-                    continue;
+        // If requested, check whether APK Signature Scheme v2 signature was stripped.
+        if (signatureSchemeRollbackProtectionsEnforced) {
+            String apkSignatureSchemeIdList =
+                    attributes.getValue(
+                            ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME);
+            if (apkSignatureSchemeIdList != null) {
+                // This field contains a comma-separated list of APK signature scheme IDs which
+                // were used to sign this APK. If an ID is known to us, it means signatures of that
+                // scheme were stripped from the APK because otherwise we wouldn't have fallen back
+                // to verifying the APK using the JAR signature scheme.
+                boolean v2SignatureGenerated = false;
+                StringTokenizer tokenizer = new StringTokenizer(apkSignatureSchemeIdList, ",");
+                while (tokenizer.hasMoreTokens()) {
+                    String idText = tokenizer.nextToken().trim();
+                    if (idText.isEmpty()) {
+                        continue;
+                    }
+                    int id;
+                    try {
+                        id = Integer.parseInt(idText);
+                    } catch (Exception ignored) {
+                        continue;
+                    }
+                    if (id == ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID) {
+                        // This APK was supposed to be signed with APK Signature Scheme v2 but no
+                        // such signature was found.
+                        v2SignatureGenerated = true;
+                        break;
+                    }
                 }
-                int id;
-                try {
-                    id = Integer.parseInt(idText);
-                } catch (Exception ignored) {
-                    continue;
-                }
-                if (id == ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID) {
-                    // This APK was supposed to be signed with APK Signature Scheme v2 but no such
-                    // signature was found.
-                    v2SignatureGenerated = true;
-                    break;
-                }
-            }
 
-            if (v2SignatureGenerated) {
-                throw new SecurityException(signatureFile + " indicates " + jarName + " is signed"
-                        + " using APK Signature Scheme v2, but no such signature was found."
-                        + " Signature stripped?");
+                if (v2SignatureGenerated) {
+                    throw new SecurityException(signatureFile + " indicates " + jarName
+                            + " is signed using APK Signature Scheme v2, but no such signature was"
+                            + " found. Signature stripped?");
+                }
             }
         }
 
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index a12434c0..41c44f1b 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.Nullable;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -51,8 +52,8 @@
      * @param paint The paint used when the layer is drawn into the destination canvas.
      * @see View#setLayerPaint(android.graphics.Paint)
      */
-    public void setLayerPaint(Paint paint) {
-        nSetLayerPaint(mFinalizer.get(), paint.getNativeInstance());
+    public void setLayerPaint(@Nullable Paint paint) {
+        nSetLayerPaint(mFinalizer.get(), paint != null ? paint.getNativeInstance() : 0);
         mRenderer.pushLayerUpdate(this);
     }
 
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 70d0513..707300f 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -95,5 +95,5 @@
     /**
      * Called when Keyboard Shortcuts are requested for the window.
      */
-    void requestAppKeyboardShortcuts(IResultReceiver receiver);
+    void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId);
 }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index d8b7421..7af4a1f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -387,7 +387,7 @@
      *
      * @param receiver The receiver to deliver the results to.
      */
-    void requestAppKeyboardShortcuts(IResultReceiver receiver);
+    void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId);
 
     /**
      * Retrieves the current stable insets from the primary display.
diff --git a/core/java/android/view/KeyboardShortcutInfo.java b/core/java/android/view/KeyboardShortcutInfo.java
index 2c9006d..c2bd347 100644
--- a/core/java/android/view/KeyboardShortcutInfo.java
+++ b/core/java/android/view/KeyboardShortcutInfo.java
@@ -30,31 +30,46 @@
     private final CharSequence mLabel;
     private final Icon mIcon;
     private final char mBaseCharacter;
+    private final int mKeycode;
     private final int mModifiers;
 
     /**
      * @param label The label that identifies the action performed by this shortcut.
      * @param icon An icon that identifies the action performed by this shortcut.
-     * @param baseCharacter The character that triggers the shortcut.
+     * @param keycode The keycode that triggers the shortcut. This should be a valid constant
+     *     defined in {@link KeyEvent}.
      * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
      *     These should be a combination of {@link KeyEvent#META_CTRL_ON},
-     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON} and
-     *     {@link KeyEvent#META_ALT_ON}.
+     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON},
+     *     {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_FUNCTION_ON} and
+     *     {@link KeyEvent#META_SYM_ON}.
      *
      * @hide
      */
     public KeyboardShortcutInfo(
-            @Nullable CharSequence label, @Nullable Icon icon, char baseCharacter, int modifiers) {
+            @Nullable CharSequence label, @Nullable Icon icon, int keycode, int modifiers) {
         mLabel = label;
         mIcon = icon;
-        checkArgument(baseCharacter != MIN_VALUE);
-        mBaseCharacter = baseCharacter;
+        mBaseCharacter = MIN_VALUE;
+        checkArgument(keycode > KeyEvent.KEYCODE_UNKNOWN && keycode <= KeyEvent.getMaxKeyCode());
+        mKeycode = keycode;
         mModifiers = modifiers;
     }
 
     /**
-     * Convenience constructor for shortcuts with a label and no icon.
-     *
+     * @param label The label that identifies the action performed by this shortcut.
+     * @param keycode The keycode that triggers the shortcut. This should be a valid constant
+     *     defined in {@link KeyEvent}.
+     * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
+     *     These should be a combination of {@link KeyEvent#META_CTRL_ON},
+     *     {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON} and
+     *     {@link KeyEvent#META_ALT_ON}.
+     */
+    public KeyboardShortcutInfo(CharSequence label, int keycode, int modifiers) {
+        this(label, null, keycode, modifiers);
+    }
+
+    /**
      * @param label The label that identifies the action performed by this shortcut.
      * @param baseCharacter The character that triggers the shortcut.
      * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
@@ -66,14 +81,16 @@
         mLabel = label;
         checkArgument(baseCharacter != MIN_VALUE);
         mBaseCharacter = baseCharacter;
+        mKeycode = KeyEvent.KEYCODE_UNKNOWN;
         mModifiers = modifiers;
         mIcon = null;
     }
 
     private KeyboardShortcutInfo(Parcel source) {
         mLabel = source.readCharSequence();
-        mIcon = (Icon) source.readParcelable(null);
+        mIcon = source.readParcelable(null);
         mBaseCharacter = (char) source.readInt();
+        mKeycode = source.readInt();
         mModifiers = source.readInt();
     }
 
@@ -96,7 +113,16 @@
     }
 
     /**
-     * Returns the base character that, combined with the modifiers, triggers this shortcut.
+     * Returns the base keycode that, combined with the modifiers, triggers this shortcut. If the
+     * base character was set instead, returns {@link KeyEvent#KEYCODE_UNKNOWN}.
+     */
+    public int getKeycode() {
+        return mKeycode;
+    }
+
+    /**
+     * Returns the base character that, combined with the modifiers, triggers this shortcut. If the
+     * keycode was set instead, returns {@link Character#MIN_VALUE}.
      */
     public char getBaseCharacter() {
         return mBaseCharacter;
@@ -119,6 +145,7 @@
         dest.writeCharSequence(mLabel);
         dest.writeParcelable(mIcon, 0);
         dest.writeInt(mBaseCharacter);
+        dest.writeInt(mKeycode);
         dest.writeInt(mModifiers);
     }
 
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index a45c18d..a19254f 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -259,7 +259,7 @@
         return nSetLayerType(mNativeRenderNode, layerType);
     }
 
-    public boolean setLayerPaint(Paint paint) {
+    public boolean setLayerPaint(@Nullable Paint paint) {
         return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
     }
 
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 1be4810..1a712c3 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -133,7 +134,6 @@
      */
     public TextureView(Context context) {
         super(context);
-        init();
     }
 
     /**
@@ -144,7 +144,6 @@
      */
     public TextureView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        init();
     }
 
     /**
@@ -158,7 +157,6 @@
      */
     public TextureView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        init();
     }
 
     /**
@@ -176,11 +174,6 @@
      */
     public TextureView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        mLayerPaint = new Paint();
     }
 
     /**
@@ -260,7 +253,7 @@
      * method will however be taken into account when rendering the content of
      * this TextureView.
      *
-     * @param layerType The ype of layer to use with this view, must be one of
+     * @param layerType The type of layer to use with this view, must be one of
      *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
      *        {@link #LAYER_TYPE_HARDWARE}
      * @param paint The paint used to compose the layer. This argument is optional
@@ -268,16 +261,16 @@
      *        {@link #LAYER_TYPE_NONE}
      */
     @Override
-    public void setLayerType(int layerType, Paint paint) {
-        if (paint != mLayerPaint) {
-            mLayerPaint = paint == null ? new Paint() : paint;
-            invalidate();
-        }
+    public void setLayerType(int layerType, @Nullable Paint paint) {
+        setLayerPaint(paint);
     }
 
     @Override
-    public void setLayerPaint(Paint paint) {
-        setLayerType(/* ignored */ 0, paint);
+    public void setLayerPaint(@Nullable Paint paint) {
+        if (paint != mLayerPaint) {
+            mLayerPaint = paint;
+            invalidate();
+        }
     }
 
     /**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6d35a58..83c6e9e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11741,7 +11741,7 @@
         }
     }
 
-   /**
+    /**
      * Utility method to retrieve the inverse of the current mMatrix property.
      * We cache the matrix to avoid recalculating it when transform properties
      * have not changed.
@@ -15626,7 +15626,7 @@
      *
      * @attr ref android.R.styleable#View_layerType
      */
-    public void setLayerType(int layerType, Paint paint) {
+    public void setLayerType(int layerType, @Nullable Paint paint) {
         if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
             throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
                     + "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
@@ -15645,8 +15645,7 @@
         }
 
         mLayerType = layerType;
-        final boolean layerDisabled = (mLayerType == LAYER_TYPE_NONE);
-        mLayerPaint = layerDisabled ? null : (paint == null ? new Paint() : paint);
+        mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : paint;
         mRenderNode.setLayerPaint(mLayerPaint);
 
         // draw() behaves differently if we are on a layer, so we need to
@@ -15680,12 +15679,12 @@
      *
      * @see #setLayerType(int, android.graphics.Paint)
      */
-    public void setLayerPaint(Paint paint) {
+    public void setLayerPaint(@Nullable Paint paint) {
         int layerType = getLayerType();
         if (layerType != LAYER_TYPE_NONE) {
-            mLayerPaint = paint == null ? new Paint() : paint;
+            mLayerPaint = paint;
             if (layerType == LAYER_TYPE_HARDWARE) {
-                if (mRenderNode.setLayerPaint(mLayerPaint)) {
+                if (mRenderNode.setLayerPaint(paint)) {
                     invalidateViewProperty(false, false);
                 }
             } else {
@@ -16855,7 +16854,7 @@
                 canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
             } else {
                 // use layer paint to draw the bitmap, merging the two alphas, but also restore
-                int layerPaintAlpha = mLayerPaint.getAlpha();
+                int layerPaintAlpha = mLayerPaint != null ? mLayerPaint.getAlpha() : 255;
                 mLayerPaint.setAlpha((int) (alpha * layerPaintAlpha));
                 canvas.drawBitmap(cache, 0.0f, 0.0f, mLayerPaint);
                 mLayerPaint.setAlpha(layerPaintAlpha);
@@ -22187,7 +22186,7 @@
     /**
      * @hide
      */
-    public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> data) {
+    public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> data, int deviceId) {
         // Do nothing.
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a2295ce..fdf6979 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -16,7 +16,8 @@
 
 package android.view;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowCallbacks.RESIZE_MODE_DOCKED_DIVIDER;
+import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -96,8 +97,8 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.concurrent.CountDownLatch;
 import java.util.HashSet;
+import java.util.concurrent.CountDownLatch;
 
 /**
  * The top of a view hierarchy, implementing the needed protocol between View
@@ -146,9 +147,6 @@
      */
     static final int MAX_TRACKBALL_DELAY = 250;
 
-    private static final int RESIZE_MODE_FREEFORM = 0;
-    private static final int RESIZE_MODE_DOCKED_DIVIDER = 1;
-
     static final ThreadLocal<HandlerActionQueue> sRunQueues = new ThreadLocal<HandlerActionQueue>();
 
     static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList();
@@ -233,6 +231,7 @@
     boolean mIsAnimating;
 
     private boolean mDragResizing;
+    private boolean mInvalidateRootRequested;
     private int mResizeMode;
     private int mCanvasOffsetX;
     private int mCanvasOffsetY;
@@ -1828,12 +1827,12 @@
                 final boolean dragResizing = freeformResizing || dockedResizing;
                 if (mDragResizing != dragResizing) {
                     if (dragResizing) {
-                        startDragResizing(mPendingBackDropFrame,
-                                mWinFrame.equals(mPendingBackDropFrame), mPendingVisibleInsets,
-                                mPendingStableInsets);
                         mResizeMode = freeformResizing
                                 ? RESIZE_MODE_FREEFORM
                                 : RESIZE_MODE_DOCKED_DIVIDER;
+                        startDragResizing(mPendingBackDropFrame,
+                                mWinFrame.equals(mPendingBackDropFrame), mPendingVisibleInsets,
+                                mPendingStableInsets, mResizeMode);
                     } else {
                         // We shouldn't come here, but if we come we should end the resize.
                         endDragResizing();
@@ -2438,6 +2437,11 @@
     @Override
     public void onHardwarePostDraw(DisplayListCanvas canvas) {
         drawAccessibilityFocusedDrawableIfNeeded(canvas);
+        synchronized (mWindowCallbacks) {
+            for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+                mWindowCallbacks.get(i).onPostDraw(canvas);
+            }
+        }
     }
 
     /**
@@ -2675,7 +2679,8 @@
         if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
             if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
                 // If accessibility focus moved, always invalidate the root.
-                boolean invalidateRoot = accessibilityFocusDirty;
+                boolean invalidateRoot = accessibilityFocusDirty || mInvalidateRootRequested;
+                mInvalidateRootRequested = false;
 
                 // Draw with hardware renderer.
                 mIsAnimating = false;
@@ -2908,6 +2913,14 @@
         return mAttachInfo.mAccessibilityFocusDrawable;
     }
 
+    /**
+     * Requests that the root render node is invalidated next time we perform a draw, such that
+     * {@link WindowCallbacks#onPostDraw} gets called.
+     */
+    public void requestInvalidateRootRenderNode() {
+        mInvalidateRootRequested = true;
+    }
+
     boolean scrollToRectOrFocus(Rect rectangle, boolean immediate) {
         final Rect ci = mAttachInfo.mContentInsets;
         final Rect vi = mAttachInfo.mVisibleInsets;
@@ -3287,7 +3300,6 @@
     private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
     private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
     private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
-    private final static int MSG_FINISH_INPUT_CONNECTION = 12;
     private final static int MSG_CHECK_FOCUS = 13;
     private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14;
     private final static int MSG_DISPATCH_DRAG_EVENT = 15;
@@ -3327,8 +3339,6 @@
                     return "MSG_DISPATCH_GET_NEW_SURFACE";
                 case MSG_DISPATCH_KEY_FROM_IME:
                     return "MSG_DISPATCH_KEY_FROM_IME";
-                case MSG_FINISH_INPUT_CONNECTION:
-                    return "MSG_FINISH_INPUT_CONNECTION";
                 case MSG_CHECK_FOCUS:
                     return "MSG_CHECK_FOCUS";
                 case MSG_CLOSE_SYSTEM_DIALOGS:
@@ -3549,12 +3559,6 @@
                 }
                 enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
             } break;
-            case MSG_FINISH_INPUT_CONNECTION: {
-                InputMethodManager imm = InputMethodManager.peekInstance();
-                if (imm != null) {
-                    imm.reportFinishInputConnection((InputConnection)msg.obj);
-                }
-            } break;
             case MSG_CHECK_FOCUS: {
                 InputMethodManager imm = InputMethodManager.peekInstance();
                 if (imm != null) {
@@ -3594,8 +3598,9 @@
                 handleDispatchWindowShown();
             } break;
             case MSG_REQUEST_KEYBOARD_SHORTCUTS: {
-                IResultReceiver receiver = (IResultReceiver) msg.obj;
-                handleRequestKeyboardShortcuts(receiver);
+                final IResultReceiver receiver = (IResultReceiver) msg.obj;
+                final int deviceId = msg.arg1;
+                handleRequestKeyboardShortcuts(receiver, deviceId);
             } break;
             case MSG_UPDATE_POINTER_ICON: {
                 MotionEvent event = (MotionEvent) msg.obj;
@@ -5516,11 +5521,11 @@
         mAttachInfo.mTreeObserver.dispatchOnWindowShown();
     }
 
-    public void handleRequestKeyboardShortcuts(IResultReceiver receiver) {
+    public void handleRequestKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
         Bundle data = new Bundle();
         ArrayList<KeyboardShortcutGroup> list = new ArrayList<>();
         if (mView != null) {
-            mView.requestKeyboardShortcuts(list);
+            mView.requestKeyboardShortcuts(list, deviceId);
         }
         data.putParcelableArrayList(WindowManager.PARCEL_KEY_SHORTCUTS_ARRAY, list);
         try {
@@ -5864,11 +5869,6 @@
         }
     }
 
-    public void dispatchFinishInputConnection(InputConnection connection) {
-        Message msg = mHandler.obtainMessage(MSG_FINISH_INPUT_CONNECTION, connection);
-        mHandler.sendMessage(msg);
-    }
-
     public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
             Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
             Configuration newConfig, Rect backDropFrame, boolean forceLayout,
@@ -6482,8 +6482,9 @@
         }
     }
 
-    public void dispatchRequestKeyboardShortcuts(IResultReceiver receiver) {
-        mHandler.obtainMessage(MSG_REQUEST_KEYBOARD_SHORTCUTS, receiver).sendToTarget();
+    public void dispatchRequestKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
+        mHandler.obtainMessage(
+                MSG_REQUEST_KEYBOARD_SHORTCUTS, deviceId, 0, receiver).sendToTarget();
     }
 
     /**
@@ -7060,11 +7061,11 @@
         }
 
         @Override
-        public void requestAppKeyboardShortcuts(IResultReceiver receiver) {
-          ViewRootImpl viewAncestor = mViewAncestor.get();
-          if (viewAncestor != null) {
-            viewAncestor.dispatchRequestKeyboardShortcuts(receiver);
-          }
+        public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
+            ViewRootImpl viewAncestor = mViewAncestor.get();
+            if (viewAncestor != null) {
+                viewAncestor.dispatchRequestKeyboardShortcuts(receiver, deviceId);
+            }
         }
     }
 
@@ -7088,13 +7089,13 @@
      * Start a drag resizing which will inform all listeners that a window resize is taking place.
      */
     private void startDragResizing(Rect initialBounds, boolean fullscreen, Rect systemInsets,
-            Rect stableInsets) {
+            Rect stableInsets, int resizeMode) {
         if (!mDragResizing) {
             mDragResizing = true;
             synchronized (mWindowCallbacks) {
                 for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
                     mWindowCallbacks.get(i).onWindowDragResizeStart(initialBounds, fullscreen,
-                            systemInsets, stableInsets);
+                            systemInsets, stableInsets, resizeMode);
                 }
             }
             mFullRedrawNeeded = true;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 63f3744..36ee3e6 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -565,9 +565,10 @@
          *
          * @param data The data list to populate with shortcuts.
          * @param menu The current menu, which may be null.
+         * @param deviceId The id for the connected device the shortcuts should be provided for.
          */
         default public void onProvideKeyboardShortcuts(
-                List<KeyboardShortcutGroup> data, @Nullable Menu menu) { };
+                List<KeyboardShortcutGroup> data, @Nullable Menu menu, int deviceId) { };
     }
 
     /** @hide */
diff --git a/core/java/android/view/WindowCallbackWrapper.java b/core/java/android/view/WindowCallbackWrapper.java
index bed74e9..8f2d2e1 100644
--- a/core/java/android/view/WindowCallbackWrapper.java
+++ b/core/java/android/view/WindowCallbackWrapper.java
@@ -154,8 +154,9 @@
     }
 
     @Override
-    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {
-        mWrapped.onProvideKeyboardShortcuts(data, menu);
+    public void onProvideKeyboardShortcuts(
+            List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
+        mWrapped.onProvideKeyboardShortcuts(data, menu, deviceId);
     }
 }
 
diff --git a/core/java/android/view/WindowCallbacks.java b/core/java/android/view/WindowCallbacks.java
index d2bfca7..b2dc1e9 100644
--- a/core/java/android/view/WindowCallbacks.java
+++ b/core/java/android/view/WindowCallbacks.java
@@ -26,6 +26,11 @@
  * @hide
  */
 public interface WindowCallbacks {
+
+    public static final int RESIZE_MODE_INVALID = -1;
+    public static final int RESIZE_MODE_FREEFORM = 0;
+    public static final int RESIZE_MODE_DOCKED_DIVIDER = 1;
+
     /**
      * Called by the system when the window got changed by the user, before the layouter got called.
      * It also gets called when the insets changed, or when the window switched between a fullscreen
@@ -51,7 +56,7 @@
      * @param stableInsets The stable insets for the window.
      */
     void onWindowDragResizeStart(Rect initialBounds, boolean fullscreen, Rect systemInsets,
-            Rect stableInsets);
+            Rect stableInsets, int resizeMode);
 
     /**
      * Called when a drag resize ends.
@@ -69,4 +74,13 @@
      * @param reportNextDraw Whether it should report when the requested draw finishes.
      */
     void onRequestDraw(boolean reportNextDraw);
+
+    /**
+     * Called after all the content has drawn and the callback now has the ability to draw something
+     * on top of everything. Call {@link ViewRootImpl#requestInvalidateRootRenderNode} when this
+     * content needs to be redrawn.
+     *
+     * @param canvas The canvas to draw on.
+     */
+    void onPostDraw(DisplayListCanvas canvas);
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 17f1991..03dcf99 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -158,7 +158,7 @@
      *
      * @hide
      */
-    public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver);
+    public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId);
 
     public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
         /**
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 6e11671..f8c7d68 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -125,7 +125,8 @@
     }
 
     @Override
-    public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver) {
+    public void requestAppKeyboardShortcuts(
+            final KeyboardShortcutsReceiver receiver, int deviceId) {
         IResultReceiver resultReceiver = new IResultReceiver.Stub() {
             @Override
             public void send(int resultCode, Bundle resultData) throws RemoteException {
@@ -136,7 +137,7 @@
         };
         try {
             WindowManagerGlobal.getWindowManagerService()
-                .requestAppKeyboardShortcuts(resultReceiver);
+                .requestAppKeyboardShortcuts(resultReceiver, deviceId);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 655c9b3..7f44bac 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -59,4 +59,8 @@
             boolean touchExplorationEnabled);
 
     IBinder getWindowToken(int windowId, int userId);
+
+    void enableAccessibilityService(in ComponentName service, int userId);
+
+    void disableAccessibilityService(in ComponentName service, int userId);
 }
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 6a830f8..a3c49c5 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -158,8 +158,8 @@
      *
      * @hide
      */
-    protected void reportFinish() {
-        // Intentionaly empty
+    public void reportFinish() {
+        // Intentionally empty
     }
 
     /**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 1d89cd0..4bb0c3c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -531,22 +531,25 @@
 
     private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
         private final InputMethodManager mParentInputMethodManager;
-        private boolean mActive;
 
         public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn,
                 final InputMethodManager inputMethodManager) {
             super(mainLooper, conn);
             mParentInputMethodManager = inputMethodManager;
-            mActive = true;
         }
 
         @Override
         public boolean isActive() {
-            return mParentInputMethodManager.mActive && mActive;
+            return mParentInputMethodManager.mActive && !isFinished();
         }
 
         void deactivate() {
-            mActive = false;
+            if (isFinished()) {
+                // This is a small performance optimization.  Still only the 1st call of
+                // reportFinish() will take effect.
+                return;
+            }
+            reportFinish();
         }
 
         @Override
@@ -563,7 +566,7 @@
         public String toString() {
             return "ControlledInputConnectionWrapper{"
                     + "connection=" + getInputConnection()
-                    + " mActive=" + mActive
+                    + " finished=" + isFinished()
                     + " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
                     + "}";
         }
@@ -837,7 +840,6 @@
                     throw e.rethrowFromSystemServer();
                 }
             }
-            notifyInputConnectionFinished();
             mServedView = null;
             mCompletions = null;
             mServedConnecting = false;
@@ -845,48 +847,6 @@
         }
     }
 
-    /**
-     * Notifies the served view that the current InputConnection will no longer be used.
-     */
-    private void notifyInputConnectionFinished() {
-        if (mServedView == null || mServedInputConnectionWrapper == null) {
-            return;
-        }
-        final InputConnection inputConnection = mServedInputConnectionWrapper.getInputConnection();
-        if (inputConnection == null) {
-            return;
-        }
-        // We need to tell the previously served view that it is no
-        // longer the input target, so it can reset its state.  Schedule
-        // this call on its window's Handler so it will be on the correct
-        // thread and outside of our lock.
-        ViewRootImpl viewRootImpl = mServedView.getViewRootImpl();
-        if (viewRootImpl != null) {
-            // This will result in a call to reportFinishInputConnection() below.
-            viewRootImpl.dispatchFinishInputConnection(inputConnection);
-        }
-    }
-
-    /**
-     * Called from the FINISH_INPUT_CONNECTION message above.
-     * @hide
-     */
-    public void reportFinishInputConnection(InputConnection ic) {
-        final InputConnection currentConnection;
-        if (mServedInputConnectionWrapper == null) {
-            currentConnection = null;
-        } else {
-            currentConnection = mServedInputConnectionWrapper.getInputConnection();
-        }
-        if (currentConnection != ic) {
-            ic.finishComposingText();
-            // To avoid modifying the public InputConnection interface
-            if (ic instanceof BaseInputConnection) {
-                ((BaseInputConnection) ic).reportFinish();
-            }
-        }
-    }
-
     public void displayCompletions(View view, CompletionInfo[] completions) {
         checkFocus();
         synchronized (mH) {
@@ -1252,8 +1212,10 @@
             // Hook 'em up and let 'er rip.
             mCurrentTextBoxAttribute = tba;
             mServedConnecting = false;
-            // Notify the served view that its previous input connection is finished
-            notifyInputConnectionFinished();
+            if (mServedInputConnectionWrapper != null) {
+                mServedInputConnectionWrapper.deactivate();
+                mServedInputConnectionWrapper = null;
+            }
             ControlledInputConnectionWrapper servedContext;
             final int missingMethodFlags;
             if (ic != null) {
@@ -1278,9 +1240,6 @@
                 servedContext = null;
                 missingMethodFlags = 0;
             }
-            if (mServedInputConnectionWrapper != null) {
-                mServedInputConnectionWrapper.deactivate();
-            }
             mServedInputConnectionWrapper = servedContext;
 
             try {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 942cbcb..59d857c 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4034,14 +4034,17 @@
                 // Don't update drawable during dragging.
                 return;
             }
+            final Layout layout = mTextView.getLayout();
+            if (layout == null) {
+                return;
+            }
             final int offset = getCurrentCursorOffset();
-            final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset);
+            final boolean isRtlCharAtOffset = isAtRtlRun(layout, offset);
             final Drawable oldDrawable = mDrawable;
             mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
             mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
             mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset);
-            final Layout layout = mTextView.getLayout();
-            if (layout != null && oldDrawable != mDrawable && isShowing()) {
+            if (oldDrawable != mDrawable && isShowing()) {
                 // Update popup window position.
                 mPositionX = getCursorHorizontalPosition(layout, offset) - mHotspotX -
                         getHorizontalOffset() + getCursorOffset();
@@ -4154,6 +4157,19 @@
 
         public abstract void updatePosition(float x, float y);
 
+        protected boolean isAtRtlRun(@NonNull Layout layout, int offset) {
+            return layout.isRtlCharAt(offset);
+        }
+
+        @VisibleForTesting
+        public float getHorizontal(@NonNull Layout layout, int offset) {
+            return layout.getPrimaryHorizontal(offset);
+        }
+
+        protected int getOffsetAtCoordinate(@NonNull Layout layout, int line, float x) {
+            return mTextView.getOffsetAtCoordinate(line, x);
+        }
+
         protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
             // A HandleView relies on the layout, which may be nulled by external methods
             Layout layout = mTextView.getLayout();
@@ -4194,7 +4210,7 @@
          * @return The clamped horizontal position for the cursor.
          */
         int getCursorHorizontalPosition(Layout layout, int offset) {
-            return (int) (layout.getPrimaryHorizontal(offset) - 0.5f);
+            return (int) (getHorizontal(layout, offset) - 0.5f);
         }
 
         public void updatePosition(int parentPositionX, int parentPositionY,
@@ -4427,7 +4443,7 @@
         int getCursorHorizontalPosition(Layout layout, int offset) {
             final Drawable drawable = mCursorCount > 0 ? mCursorDrawable[0] : null;
             if (drawable != null) {
-                final float horizontal = layout.getPrimaryHorizontal(offset);
+                final float horizontal = getHorizontal(layout, offset);
                 return clampHorizontalPosition(drawable, horizontal) + mTempRect.left;
             }
             return super.getCursorHorizontalPosition(layout, offset);
@@ -4499,10 +4515,10 @@
                     mPreviousLineTouched = mTextView.getLineAtCoordinate(y);
                 }
                 int currLine = getCurrentLineAdjustedForSlop(layout, mPreviousLineTouched, y);
-                offset = mTextView.getOffsetAtCoordinate(currLine, x);
+                offset = getOffsetAtCoordinate(layout, currLine, x);
                 mPreviousLineTouched = currLine;
             } else {
-                offset = mTextView.getOffsetForPosition(x, y);
+                offset = -1;
             }
             positionAtCursorOffset(offset, false);
             if (mTextActionMode != null) {
@@ -4612,14 +4628,14 @@
             final int anotherHandleOffset =
                     isStartHandle() ? mTextView.getSelectionEnd() : mTextView.getSelectionStart();
             int currLine = getCurrentLineAdjustedForSlop(layout, mPreviousLineTouched, y);
-            int initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
+            int initialOffset = getOffsetAtCoordinate(layout, currLine, x);
 
             if (isStartHandle() && initialOffset >= anotherHandleOffset
                     || !isStartHandle() && initialOffset <= anotherHandleOffset) {
                 // Handles have crossed, bound it to the first selected line and
                 // adjust by word / char as normal.
                 currLine = layout.getLineForOffset(anotherHandleOffset);
-                initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
+                initialOffset = getOffsetAtCoordinate(layout, currLine, x);
             }
 
             int offset = initialOffset;
@@ -4631,8 +4647,8 @@
             }
 
             final int currentOffset = getCurrentCursorOffset();
-            final boolean rtlAtCurrentOffset = layout.isRtlCharAt(currentOffset);
-            final boolean atRtl = layout.isRtlCharAt(offset);
+            final boolean rtlAtCurrentOffset = isAtRtlRun(layout, currentOffset);
+            final boolean atRtl = isAtRtlRun(layout, offset);
             final boolean isLvlBoundary = layout.isLevelBoundary(offset);
 
             // We can't determine if the user is expanding or shrinking the selection if they're
@@ -4689,14 +4705,15 @@
 
             if (isExpanding) {
                 // User is increasing the selection.
-                final boolean snapToWord = !mInWord
-                        || (isStartHandle() ? currLine < mPrevLine : currLine > mPrevLine);
+                int wordBoundary = isStartHandle() ? wordStart : wordEnd;
+                final boolean snapToWord = (!mInWord
+                        || (isStartHandle() ? currLine < mPrevLine : currLine > mPrevLine))
+                                && atRtl == isAtRtlRun(layout, wordBoundary);
                 if (snapToWord) {
                     // Sometimes words can be broken across lines (Chinese, hyphenation).
                     // We still snap to the word boundary but we only use the letters on the
                     // current line to determine if the user is far enough into the word to snap.
-                    int wordBoundary = isStartHandle() ? wordStart : wordEnd;
-                    if (layout != null && layout.getLineForOffset(wordBoundary) != currLine) {
+                    if (layout.getLineForOffset(wordBoundary) != currLine) {
                         wordBoundary = isStartHandle() ?
                                 layout.getLineStart(currLine) : layout.getLineEnd(currLine);
                     }
@@ -4717,9 +4734,9 @@
                         offset = mPreviousOffset;
                     }
                 }
-                if (layout != null && (isStartHandle() && offset < initialOffset)
+                if ((isStartHandle() && offset < initialOffset)
                         || (!isStartHandle() && offset > initialOffset)) {
-                    final float adjustedX = layout.getPrimaryHorizontal(offset);
+                    final float adjustedX = getHorizontal(layout, offset);
                     mTouchWordDelta =
                             mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
                 } else {
@@ -4728,7 +4745,7 @@
                 positionCursor = true;
             } else {
                 final int adjustedOffset =
-                        mTextView.getOffsetAtCoordinate(currLine, x - mTouchWordDelta);
+                        getOffsetAtCoordinate(layout, currLine, x - mTouchWordDelta);
                 final boolean shrinking = isStartHandle()
                         ? adjustedOffset > mPreviousOffset || currLine > mPrevLine
                         : adjustedOffset < mPreviousOffset || currLine < mPrevLine;
@@ -4737,9 +4754,9 @@
                     if (currLine != mPrevLine) {
                         // We're on a different line, so we'll snap to word boundaries.
                         offset = isStartHandle() ? wordStart : wordEnd;
-                        if (layout != null && (isStartHandle() && offset < initialOffset)
+                        if ((isStartHandle() && offset < initialOffset)
                                 || (!isStartHandle() && offset > initialOffset)) {
-                            final float adjustedX = layout.getPrimaryHorizontal(offset);
+                            final float adjustedX = getHorizontal(layout, offset);
                             mTouchWordDelta =
                                     mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
                         } else {
@@ -4754,7 +4771,7 @@
                     // Handle has jumped to the word boundary, and the user is moving
                     // their finger towards the handle, the delta should be updated.
                     mTouchWordDelta = mTextView.convertToLocalHorizontalCoordinate(x) -
-                            layout.getPrimaryHorizontal(mPreviousOffset);
+                            getHorizontal(layout, mPreviousOffset);
                 }
             }
 
@@ -4792,9 +4809,32 @@
                     isStartHandle() ? mTextView.getSelectionEnd() : mTextView.getSelectionStart();
             if ((isStartHandle() && offset >= anotherHandleOffset)
                     || (!isStartHandle() && offset <= anotherHandleOffset)) {
+                mTouchWordDelta = 0.0f;
+                final Layout layout = mTextView.getLayout();
+                if (layout != null && offset != anotherHandleOffset) {
+                    final float horiz = getHorizontal(layout, offset);
+                    final float anotherHandleHoriz = getHorizontal(layout, anotherHandleOffset,
+                            !isStartHandle());
+                    final float currentHoriz = getHorizontal(layout, mPreviousOffset);
+                    if (currentHoriz < anotherHandleHoriz && horiz < anotherHandleHoriz
+                            || currentHoriz > anotherHandleHoriz && horiz > anotherHandleHoriz) {
+                        // This handle passes another one as it crossed a direction boundary.
+                        // Don't minimize the selection, but keep the handle at the run boundary.
+                        final int currentOffset = getCurrentCursorOffset();
+                        final int offsetToGetRunRange = isStartHandle() ?
+                                currentOffset : Math.max(currentOffset - 1, 0);
+                        final long range = layout.getRunRange(offsetToGetRunRange);
+                        if (isStartHandle()) {
+                            offset = TextUtils.unpackRangeStartFromLong(range);
+                        } else {
+                            offset = TextUtils.unpackRangeEndFromLong(range);
+                        }
+                        positionAtCursorOffset(offset, false);
+                        return;
+                    }
+                }
                 // Handles can not cross and selection is at least one character.
                 offset = getNextCursorOffset(anotherHandleOffset, !isStartHandle());
-                mTouchWordDelta = 0.0f;
             }
             positionAtCursorOffset(offset, false);
         }
@@ -4812,6 +4852,49 @@
             }
             return nearEdge;
         }
+
+        @Override
+        protected boolean isAtRtlRun(@NonNull Layout layout, int offset) {
+            final int offsetToCheck = isStartHandle() ? offset : Math.max(offset - 1, 0);
+            return layout.isRtlCharAt(offsetToCheck);
+        }
+
+        @Override
+        public float getHorizontal(@NonNull Layout layout, int offset) {
+            return getHorizontal(layout, offset, isStartHandle());
+        }
+
+        private float getHorizontal(@NonNull Layout layout, int offset, boolean startHandle) {
+            final int line = layout.getLineForOffset(offset);
+            final int offsetToCheck = startHandle ? offset : Math.max(offset - 1, 0);
+            final boolean isRtlChar = layout.isRtlCharAt(offsetToCheck);
+            final boolean isRtlParagraph = layout.getParagraphDirection(line) == -1;
+            return (isRtlChar == isRtlParagraph) ?
+                    layout.getPrimaryHorizontal(offset) : layout.getSecondaryHorizontal(offset);
+        }
+
+        @Override
+        protected int getOffsetAtCoordinate(@NonNull Layout layout, int line, float x) {
+            final int primaryOffset = layout.getOffsetForHorizontal(line, x, true);
+            if (!layout.isLevelBoundary(primaryOffset)) {
+                return primaryOffset;
+            }
+            final int secondaryOffset = layout.getOffsetForHorizontal(line, x, false);
+            final int currentOffset = getCurrentCursorOffset();
+            final int primaryDiff = Math.abs(primaryOffset - currentOffset);
+            final int secondaryDiff = Math.abs(secondaryOffset - currentOffset);
+            if (primaryDiff < secondaryDiff) {
+                return primaryOffset;
+            } else if (primaryDiff > secondaryDiff) {
+                return secondaryOffset;
+            } else {
+                final int offsetToCheck = isStartHandle() ?
+                        currentOffset : Math.max(currentOffset - 1, 0);
+                final boolean isRtlChar = layout.isRtlCharAt(offsetToCheck);
+                final boolean isRtlParagraph = layout.getParagraphDirection(line) == -1;
+                return isRtlChar == isRtlParagraph ? primaryOffset : secondaryOffset;
+            }
+        }
     }
 
     private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) {
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index d1b5fc8..18687c9 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -129,8 +129,8 @@
      */
     private static final int ANIMATION_STYLE_DEFAULT = -1;
 
-    private final int[] mDrawingLocation = new int[2];
-    private final int[] mScreenLocation = new int[2];
+    private final int[] mTmpDrawingLocation = new int[2];
+    private final int[] mTmpScreenLocation = new int[2];
     private final Rect mTempRect = new Rect();
 
     private Context mContext;
@@ -222,7 +222,7 @@
                         mDecorView.getLayoutParams();
 
                 updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
-                        mAnchoredGravity));
+                        p.width, p.height, mAnchoredGravity));
                 update(p.x, p.y, -1, -1, true);
             }
         }
@@ -1123,7 +1123,7 @@
 
         TransitionManager.endTransitions(mDecorView);
 
-        unregisterForViewTreeChanges();
+        detachFromAnchor();
 
         mIsShowing = true;
         mIsDropdown = false;
@@ -1206,7 +1206,7 @@
 
         TransitionManager.endTransitions(mDecorView);
 
-        registerForViewTreeChanges(anchor, xoff, yoff, gravity);
+        attachToAnchor(anchor, xoff, yoff, gravity);
 
         mIsShowing = true;
         mIsDropdown = true;
@@ -1214,7 +1214,8 @@
         final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken());
         preparePopup(p);
 
-        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity);
+        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff,
+                p.width, p.height, gravity);
         updateAboveAnchor(aboveAnchor);
 
         invokePopup(p);
@@ -1494,120 +1495,138 @@
      * to reclaim space. If scrolling is not possible or not enough, the popup
      * window gets moved on top of the anchor.
      * <p>
-     * The height must have been set on the layout parameters prior to calling
-     * this method.
+     * The results of positioning are placed in {@code outParams}.
      *
      * @param anchor the view on which the popup window must be anchored
-     * @param p the layout parameters used to display the drop down
-     * @param xoff horizontal offset used to adjust for background padding
-     * @param yoff vertical offset used to adjust for background padding
+     * @param outParams the layout parameters used to display the drop down
+     * @param xOffset absolute horizontal offset from the top of the anchor
+     * @param yOffset absolute vertical offset from the top of the anchor
      * @param gravity horizontal gravity specifying popup alignment
      * @return true if the popup is translated upwards to fit on screen
      */
-    private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p, int xoff,
-            int yoff, int gravity) {
+    private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams outParams,
+            int xOffset, int yOffset, int width, int height, int gravity) {
         final int anchorHeight = anchor.getHeight();
         final int anchorWidth = anchor.getWidth();
         if (mOverlapAnchor) {
-            yoff -= anchorHeight;
+            yOffset -= anchorHeight;
         }
 
-        anchor.getLocationInWindow(mDrawingLocation);
-        p.x = mDrawingLocation[0] + xoff;
-        p.y = mDrawingLocation[1] + anchorHeight + yoff;
+        // Initially, align to the bottom-left corner of the anchor plus offsets.
+        final int[] drawingLocation = mTmpDrawingLocation;
+        anchor.getLocationInWindow(drawingLocation);
+        outParams.x = drawingLocation[0] + xOffset;
+        outParams.y = drawingLocation[1] + anchorHeight + yOffset;
 
+        // If we need to adjust for gravity RIGHT, align to the bottom-right
+        // corner of the anchor (still accounting for offsets).
         final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection())
                 & Gravity.HORIZONTAL_GRAVITY_MASK;
         if (hgrav == Gravity.RIGHT) {
-            // Flip the location to align the right sides of the popup and
-            // anchor instead of left.
-            p.x -= mPopupWidth - anchorWidth;
+            outParams.x -= width - anchorWidth;
         }
 
-        boolean onTop = false;
+        // Let the window manager know to align the top to y.
+        outParams.gravity = Gravity.LEFT | Gravity.TOP;
 
-        p.gravity = Gravity.LEFT | Gravity.TOP;
+        final int[] screenLocation = mTmpScreenLocation;
+        anchor.getLocationOnScreen(screenLocation);
 
-        anchor.getLocationOnScreen(mScreenLocation);
         final Rect displayFrame = new Rect();
         anchor.getWindowVisibleDisplayFrame(displayFrame);
 
-        final int screenY = mScreenLocation[1] + anchorHeight + yoff;
+        boolean onTop = false;
+
         final View root = anchor.getRootView();
-        if (screenY + mPopupHeight > displayFrame.bottom
-                || p.x + mPopupWidth - root.getWidth() > 0) {
-            // If the drop down disappears at the bottom of the screen, we try
-            // to scroll a parent scrollview or move the drop down back up on
-            // top of the edit box.
+        final int screenY = screenLocation[1] + anchorHeight + yOffset;
+        final boolean tooFarDown = screenY + height > displayFrame.bottom;
+        final boolean tooFarRight = outParams.x + width > root.getWidth();
+        if (tooFarDown || tooFarRight) {
+            // If the popup extends beyond the visible area, try to scroll the
+            // parent so that it is fully visible.
             if (mAllowScrollingAnchorParent) {
                 final int scrollX = anchor.getScrollX();
                 final int scrollY = anchor.getScrollY();
-                final Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
-                        scrollY + mPopupHeight + anchorHeight + yoff);
+                final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset,
+                        scrollY + height + anchorHeight + yOffset);
                 anchor.requestRectangleOnScreen(r, true);
             }
 
-            // Now we re-evaluate the space available, and decide from that
-            // whether the pop-up will go above or below the anchor.
-            anchor.getLocationInWindow(mDrawingLocation);
-            p.x = mDrawingLocation[0] + xoff;
-            p.y = mDrawingLocation[1] + anchorHeight + yoff;
+            // Update for the new anchor position.
+            anchor.getLocationInWindow(drawingLocation);
+            outParams.x = drawingLocation[0] + xOffset;
+            outParams.y = drawingLocation[1] + anchorHeight + yOffset;
 
             // Preserve the gravity adjustment.
             if (hgrav == Gravity.RIGHT) {
-                p.x -= mPopupWidth - anchorWidth;
+                outParams.x -= width - anchorWidth;
             }
 
-            // Determine whether there is more space above or below the anchor.
-            anchor.getLocationOnScreen(mScreenLocation);
-            onTop = (displayFrame.bottom - mScreenLocation[1] - anchorHeight - yoff) <
-                    (mScreenLocation[1] - yoff - displayFrame.top);
-            if (!mOverlapAnchor) {
+            final int newScreenY = screenLocation[1] + anchorHeight + yOffset;
+            final boolean stillTooFarDown = newScreenY + height > displayFrame.bottom;
+            if (stillTooFarDown) {
+                // If the popup is still too far down, re-evaluate the space
+                // available and decide whether the pop-up will go above or
+                // below the anchor.
+                anchor.getLocationOnScreen(screenLocation);
+
+                final int below = displayFrame.bottom - screenLocation[1] - anchorHeight - yOffset;
+                final int above = screenLocation[1] - displayFrame.top + yOffset;
+                onTop = above > below;
+
                 if (onTop) {
-                    p.gravity = Gravity.LEFT | Gravity.BOTTOM;
-                    p.y = root.getHeight() - mDrawingLocation[1] + yoff;
-                } else {
-                    p.y = mDrawingLocation[1] + anchorHeight + yoff;
+                    // Move everything up.
+                    if (mOverlapAnchor) {
+                        yOffset += anchorHeight;
+                    }
+                    outParams.y = drawingLocation[1] - height + yOffset;
                 }
             }
         }
 
         if (mClipToScreen) {
-            final int winOffsetX = mScreenLocation[0] - mDrawingLocation[0];
-            final int winOffsetY = mScreenLocation[1] - mDrawingLocation[1];
-            p.x += winOffsetX;
-            p.y += winOffsetY;
-            final int displayFrameWidth = displayFrame.right - displayFrame.left;
-            final int right = p.x + p.width;
+            // Use screen coordinates for comparison against display frame.
+            final int winOffsetX = screenLocation[0] - drawingLocation[0];
+            final int winOffsetY = screenLocation[1] - drawingLocation[1];
+            outParams.x += winOffsetX;
+            outParams.y += winOffsetY;
+
+            final int right = outParams.x + width;
             if (right > displayFrame.right) {
-                p.x -= right - displayFrame.right;
+                // The popup is too far right, move it back in.
+                outParams.x -= right - displayFrame.right;
             }
 
-            if (p.x < displayFrame.left) {
-                p.x = displayFrame.left;
-                p.width = Math.min(p.width, displayFrameWidth);
+            if (outParams.x < displayFrame.left) {
+                // The popup is too far left, move it back in and clip if it's
+                // still too large.
+                outParams.x = displayFrame.left;
+
+                final int displayFrameWidth = displayFrame.width();
+                width = Math.min(width, displayFrameWidth);
             }
 
-            if (mOverlapAnchor) {
-                final int bottom = p.y + p.height;
-                if (bottom > displayFrame.bottom) {
-                    p.y -= bottom - displayFrame.bottom;
-                }
-            } else {
-                if (onTop) {
-                    final int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
-                    if (popupTop < 0) {
-                        p.y += popupTop;
-                    }
-                } else {
-                    p.y = Math.max(p.y, displayFrame.top);
-                }
+            final int bottom = outParams.y + height;
+            if (bottom > displayFrame.bottom) {
+                // The popup is too far down, move it back in.
+                outParams.y -= bottom - displayFrame.bottom;
             }
-            p.x -= winOffsetX;
-            p.y -= winOffsetY;
+
+            if (outParams.y < displayFrame.top) {
+                // The popup is too far up, move it back in and clip if
+                // it's still too large.
+                outParams.y = displayFrame.top;
+
+                final int displayFrameHeight = displayFrame.height();
+                height = Math.min(height, displayFrameHeight);
+            }
+
+            outParams.x -= winOffsetX;
+            outParams.y -= winOffsetY;
         }
 
-        p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
+        outParams.width = width;
+        outParams.height = height;
 
         return onTop;
     }
@@ -1665,7 +1684,7 @@
             anchor.getWindowVisibleDisplayFrame(displayFrame);
         }
 
-        final int[] anchorPos = mDrawingLocation;
+        final int[] anchorPos = mTmpDrawingLocation;
         anchor.getLocationOnScreen(anchorPos);
 
         final int bottomEdge = displayFrame.bottom;
@@ -1754,7 +1773,7 @@
         }
 
         // Clears the anchor view.
-        unregisterForViewTreeChanges();
+        detachFromAnchor();
 
         if (mOnDismissListener != null) {
             mOnDismissListener.onDismiss();
@@ -2018,43 +2037,40 @@
         }
 
         final WeakReference<View> oldAnchor = mAnchor;
+        final int gravity = mAnchoredGravity;
+
         final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff);
         if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) {
-            registerForViewTreeChanges(anchor, xoff, yoff, mAnchoredGravity);
+            attachToAnchor(anchor, xoff, yoff, gravity);
         } else if (needsUpdate) {
             // No need to register again if this is a DropDown, showAsDropDown already did.
             mAnchorXoff = xoff;
             mAnchorYoff = yoff;
         }
 
-        final WindowManager.LayoutParams p =
-                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
+        final LayoutParams p = (LayoutParams) mDecorView.getLayoutParams();
+        final int oldGravity = p.gravity;
+        final int oldWidth = p.width;
+        final int oldHeight = p.height;
+        final int oldX = p.x;
+        final int oldY = p.y;
 
         if (updateDimension) {
             if (width == -1) {
                 width = mPopupWidth;
-            } else {
-                mPopupWidth = width;
-                p.width = width;
             }
             if (height == -1) {
                 height = mPopupHeight;
-            } else {
-                mPopupHeight = height;
-                p.height  = height;
             }
         }
 
-        final int x = p.x;
-        final int y = p.y;
-        if (updateLocation) {
-            updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, mAnchoredGravity));
-        } else {
-            updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
-                    mAnchoredGravity));
-        }
+        final boolean aboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
+                width, height, gravity);
+        updateAboveAnchor(aboveAnchor);
 
-        update(p.x, p.y, width, height, x != p.x || y != p.y);
+        final boolean paramsChanged = oldGravity != p.gravity || oldX != p.x || oldY != p.y
+                || oldWidth != p.width || oldHeight != p.height;
+        update(p.x, p.y, p.width, p.height, paramsChanged);
     }
 
     /**
@@ -2067,7 +2083,7 @@
         public void onDismiss();
     }
 
-    private void unregisterForViewTreeChanges() {
+    private void detachFromAnchor() {
         final View anchor = mAnchor != null ? mAnchor.get() : null;
         if (anchor != null) {
             final ViewTreeObserver vto = anchor.getViewTreeObserver();
@@ -2084,8 +2100,8 @@
         mIsAnchorRootAttached = false;
     }
 
-    private void registerForViewTreeChanges(View anchor, int xoff, int yoff, int gravity) {
-        unregisterForViewTreeChanges();
+    private void attachToAnchor(View anchor, int xoff, int yoff, int gravity) {
+        detachFromAnchor();
 
         final ViewTreeObserver vto = anchor.getViewTreeObserver();
         if (vto != null) {
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index c0dce22..7bd64e5 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -26,6 +26,7 @@
 import android.os.UserHandle;
 import android.util.Slog;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.Preconditions;
 
 import java.util.HashSet;
 
@@ -72,15 +73,17 @@
 
     public void register(Context context, Looper thread, UserHandle user,
             boolean externalStorage) {
+        register(context, user, externalStorage,
+                (thread == null) ? BackgroundThread.getHandler() : new Handler(thread));
+    }
+
+    public void register(Context context, UserHandle user,
+        boolean externalStorage, Handler handler) {
         if (mRegisteredContext != null) {
             throw new IllegalStateException("Already registered");
         }
         mRegisteredContext = context;
-        if (thread == null) {
-            mRegisteredHandler = BackgroundThread.getHandler();
-        } else {
-            mRegisteredHandler = new Handler(thread);
-        }
+        mRegisteredHandler = Preconditions.checkNotNull(handler);
         if (user != null) {
             context.registerReceiverAsUser(this, user, sPackageFilt, null, mRegisteredHandler);
             context.registerReceiverAsUser(this, user, sNonDataFilt, null, mRegisteredHandler);
diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index ed4722d..2a9264d 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -21,7 +21,6 @@
 import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.Slog;
-import android.text.TextUtils;
 
 import com.android.internal.util.Preconditions;
 
@@ -140,14 +139,14 @@
     }
 
     public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
-            int dexFlags, String volumeUuid, boolean useProfiles) throws InstallerException {
+            int dexFlags, String compilerFilter, String volumeUuid) throws InstallerException {
         dexopt(apkPath, uid, "*", instructionSet, dexoptNeeded,
-                null /*outputPath*/, dexFlags, volumeUuid, useProfiles);
+                null /*outputPath*/, dexFlags, compilerFilter, volumeUuid);
     }
 
     public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
-            int dexoptNeeded, String outputPath, int dexFlags, String volumeUuid,
-            boolean useProfiles) throws InstallerException {
+            int dexoptNeeded, String outputPath, int dexFlags, String compilerFilter,
+            String volumeUuid) throws InstallerException {
         execute("dexopt",
                 apkPath,
                 uid,
@@ -156,8 +155,27 @@
                 dexoptNeeded,
                 outputPath,
                 dexFlags,
-                volumeUuid,
-                useProfiles ? '1' : '0');
+                compilerFilter,
+                volumeUuid);
+    }
+
+    public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
+        String rawReply = executeForResult("merge_profiles", uid, pkgName);
+        if (rawReply == null) {
+            throw new IllegalStateException("Unexpected null reply");
+        }
+        final String res[] = rawReply.split(" ");
+
+        if ((res == null) || (res.length != 2)) {
+            throw new InstallerException("Invalid size result: " + rawReply);
+        }
+
+        // Just as a sanity check. Anything != "true" will be interpreted as false by parseBoolean.
+        if (!res[1].equals("true") && !res[1].equals("false")) {
+            throw new InstallerException("Invalid boolean result: " + rawReply);
+        }
+
+        return Boolean.parseBoolean(res[1]);
     }
 
     private boolean connect() {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index b658f87..5980ab6 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -501,12 +501,14 @@
             for (String classPathElement : classPathElements) {
                 // System server is fully AOTed and never profiled
                 // for profile guided compilation.
+                // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
                 final int dexoptNeeded = DexFile.getDexOptNeeded(
-                        classPathElement, instructionSet, DexFile.COMPILATION_TYPE_FULL);
+                        classPathElement, instructionSet, "speed",
+                        false /* newProfile */);
                 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                     installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
-                            dexoptNeeded, 0 /*dexFlags*/, null /*volumeUuid*/,
-                            false /*useProfiles*/);
+                            dexoptNeeded, 0 /*dexFlags*/, "speed",
+                            null /*volumeUuid*/);
                 }
             }
         } catch (IOException | InstallerException e) {
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index 6931193..738aaca 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.policy;
 
+import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM;
+
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -69,6 +71,7 @@
     private ColorDrawable mNavigationBarColor;
     private boolean mOldFullscreen;
     private boolean mFullscreen;
+    private final int mResizeMode;
     private final Rect mOldSystemInsets = new Rect();
     private final Rect mOldStableInsets = new Rect();
     private final Rect mSystemInsets = new Rect();
@@ -77,7 +80,7 @@
     public BackdropFrameRenderer(DecorView decorView, ThreadedRenderer renderer, Rect initialBounds,
             Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable,
             Drawable userCaptionBackgroundDrawable, int statusBarColor, int navigationBarColor,
-            boolean fullscreen, Rect systemInsets, Rect stableInsets) {
+            boolean fullscreen, Rect systemInsets, Rect stableInsets, int resizeMode) {
         setName("ResizeFrame");
 
         mRenderer = renderer;
@@ -98,6 +101,7 @@
         mStableInsets.set(stableInsets);
         mOldSystemInsets.set(systemInsets);
         mOldStableInsets.set(stableInsets);
+        mResizeMode = resizeMode;
         synchronized (this) {
             redrawLocked(initialBounds, fullscreen, mSystemInsets, mStableInsets);
         }
@@ -266,11 +270,16 @@
             mLastXOffset = xOffset;
             mLastYOffset = yOffset;
 
-            mRenderer.setContentDrawBounds(
-                    mLastXOffset,
-                    mLastYOffset,
-                    mLastXOffset + mLastContentWidth,
-                    mLastYOffset + mLastCaptionHeight + mLastContentHeight);
+            // Only clip the content to the bounds if we are not fullscreen. In the other case, we
+            // actually need to draw outside these.
+            if (mResizeMode == RESIZE_MODE_FREEFORM) {
+                mRenderer.setContentDrawBounds(
+                        mLastXOffset,
+                        mLastYOffset,
+                        mLastXOffset + mLastContentWidth,
+                        mLastYOffset + mLastCaptionHeight + mLastContentHeight);
+            }
+
             // If this was the first call and redrawLocked got already called prior
             // to us, we should re-issue a redrawLocked now.
             return firstCall
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index fbd8fb5..9904893f 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -39,8 +39,11 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.RemoteException;
@@ -49,6 +52,7 @@
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.ContextThemeWrapper;
+import android.view.DisplayListCanvas;
 import android.view.Gravity;
 import android.view.InputQueue;
 import android.view.KeyEvent;
@@ -88,6 +92,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -211,6 +216,11 @@
     private boolean mApplyFloatingVerticalInsets = false;
     private boolean mApplyFloatingHorizontalInsets = false;
 
+    private int mResizeMode = RESIZE_MODE_INVALID;
+    private final int mResizeShadowSize;
+    private final Paint mVerticalResizeShadowPaint = new Paint();
+    private final Paint mHorizontalResizeShadowPaint = new Paint();
+
     DecorView(Context context, int featureId, PhoneWindow window,
             WindowManager.LayoutParams params) {
         super(context);
@@ -233,6 +243,10 @@
         setWindow(window);
 
         updateLogTag(params);
+
+        mResizeShadowSize = context.getResources().getDimensionPixelSize(
+                R.dimen.resize_shadow_size);
+        initResizingPaints();
     }
 
     void setBackgroundFallback(int resId) {
@@ -699,6 +713,10 @@
         // our shadow elevation.
         updateElevation();
         mAllowUpdateElevation = true;
+
+        if (changed && mResizeMode == RESIZE_MODE_DOCKED_DIVIDER) {
+            getViewRootImpl().requestInvalidateRootRenderNode();
+        }
     }
 
     @Override
@@ -1907,7 +1925,7 @@
 
     @Override
     public void onWindowDragResizeStart(Rect initialBounds, boolean fullscreen, Rect systemInsets,
-            Rect stableInsets) {
+            Rect stableInsets, int resizeMode) {
         if (mWindow.isDestroyed()) {
             // If the owner's window is gone, we should not be able to come here anymore.
             releaseThreadedRenderer();
@@ -1923,7 +1941,7 @@
                     initialBounds, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
                     mUserCaptionBackgroundDrawable, getCurrentColor(mStatusColorViewState),
                     getCurrentColor(mNavigationColorViewState), fullscreen, systemInsets,
-                    stableInsets);
+                    stableInsets, resizeMode);
 
             // Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
             // If we want to get the shadow shown while resizing, we would need to elevate a new
@@ -1932,12 +1950,16 @@
 
             updateColorViews(null /* insets */, false);
         }
+        mResizeMode = resizeMode;
+        getViewRootImpl().requestInvalidateRootRenderNode();
     }
 
     @Override
     public void onWindowDragResizeEnd() {
         releaseThreadedRenderer();
         updateColorViews(null /* insets */, false);
+        mResizeMode = RESIZE_MODE_INVALID;
+        getViewRootImpl().requestInvalidateRootRenderNode();
     }
 
     @Override
@@ -1960,6 +1982,41 @@
         }
     }
 
+    @Override
+    public void onPostDraw(DisplayListCanvas canvas) {
+        drawResizingShadowIfNeeded(canvas);
+    }
+
+    private void initResizingPaints() {
+        final int startColor = mContext.getResources().getColor(
+                R.color.resize_shadow_start_color, null);
+        final int endColor = mContext.getResources().getColor(
+                R.color.resize_shadow_end_color, null);
+        final int middleColor = (startColor + endColor) / 2;
+        mHorizontalResizeShadowPaint.setShader(new LinearGradient(
+                0, 0, 0, mResizeShadowSize, new int[] { startColor, middleColor, endColor },
+                new float[] { 0f, 0.3f, 1f }, Shader.TileMode.CLAMP));
+        mVerticalResizeShadowPaint.setShader(new LinearGradient(
+                0, 0, mResizeShadowSize, 0, new int[] { startColor, middleColor, endColor },
+                new float[] { 0f, 0.3f, 1f }, Shader.TileMode.CLAMP));
+    }
+
+    private void drawResizingShadowIfNeeded(DisplayListCanvas canvas) {
+        if (mResizeMode != RESIZE_MODE_DOCKED_DIVIDER || mWindow.mIsFloating
+                || mWindow.isTranslucent()
+                || (mWindow.getAttributes().flags & FLAG_SHOW_WALLPAPER) != 0) {
+            return;
+        }
+        canvas.save();
+        canvas.translate(0, getHeight() - mFrameOffsets.bottom);
+        canvas.drawRect(0, 0, getWidth(), mResizeShadowSize, mHorizontalResizeShadowPaint);
+        canvas.restore();
+        canvas.save();
+        canvas.translate(getWidth() - mFrameOffsets.right, 0);
+        canvas.drawRect(0, 0, mResizeShadowSize, getHeight(), mVerticalResizeShadowPaint);
+        canvas.restore();
+    }
+
     /** Release the renderer thread which is usually done when the user stops resizing. */
     private void releaseThreadedRenderer() {
         if (mResizingBackgroundDrawable != null && mLastBackgroundDrawableCb != null) {
@@ -2070,10 +2127,10 @@
      * @hide
      */
     @Override
-    public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> list) {
+    public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> list, int deviceId) {
         final PanelFeatureState st = mWindow.getPanelState(FEATURE_OPTIONS_PANEL, false);
         if (!mWindow.isDestroyed() && st != null && mWindow.getCallback() != null) {
-            mWindow.getCallback().onProvideKeyboardShortcuts(list, st.menu);
+            mWindow.getCallback().onProvideKeyboardShortcuts(list, st.menu, deviceId);
         }
     }
 
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 7637eec..794a6d6 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -157,6 +157,7 @@
     InputQueue.Callback mTakeInputQueueCallback;
 
     boolean mIsFloating;
+    private boolean mIsTranslucent;
 
     private LayoutInflater mLayoutInflater;
 
@@ -490,6 +491,10 @@
         return mIsFloating;
     }
 
+    public boolean isTranslucent() {
+        return mIsTranslucent;
+    }
+
     /**
      * Return a LayoutInflater instance that can be used to inflate XML view layout
      * resources for use in this Window.
@@ -2400,6 +2405,8 @@
             requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
         }
 
+        mIsTranslucent = a.getBoolean(R.styleable.Window_windowIsTranslucent, false);
+
         final Context context = getContext();
         final int targetSdk = context.getApplicationInfo().targetSdkVersion;
         final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 64c5b8d..9e5c238 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -65,7 +65,7 @@
     void cancelPreloadRecentApps();
     void showScreenPinningRequest();
 
-    void toggleKeyboardShortcutsMenu();
+    void toggleKeyboardShortcutsMenu(int deviceId);
 
     /**
      * Notifies the status bar that an app transition is pending to delay applying some flags with
@@ -88,6 +88,11 @@
      */
     void appTransitionStarting(long statusBarAnimationsStartTime, long statusBarAnimationsDuration);
 
+    /**
+     * Notifies the status bar that an app transition is done.
+     */
+    void appTransitionFinished();
+
     void showAssistDisclosure();
     void startAssist(in Bundle args);
 
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 8acf5d3..ee3f937 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -71,7 +71,7 @@
     void preloadRecentApps();
     void cancelPreloadRecentApps();
 
-    void toggleKeyboardShortcutsMenu();
+    void toggleKeyboardShortcutsMenu(int deviceId);
 
     /**
      * Notifies the status bar that an app transition is pending to delay applying some flags with
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index 53cb56e..c46851e 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -35,6 +35,20 @@
     }
 
     /**
+     * Ensures that an expression checking an argument is true.
+     *
+     * @param expression the expression to check
+     * @param errorMessage the exception message to use if the check fails; will
+     *     be converted to a string using {@link String#valueOf(Object)}
+     * @throws IllegalArgumentException if {@code expression} is false
+     */
+    public static void checkArgument(boolean expression, final Object errorMessage) {
+        if (!expression) {
+            throw new IllegalArgumentException(String.valueOf(errorMessage));
+        }
+    }
+
+    /**
      * Ensures that an string reference passed as a parameter to the calling
      * method is not empty.
      *
diff --git a/core/java/com/android/internal/util/ProgressReporter.java b/core/java/com/android/internal/util/ProgressReporter.java
new file mode 100644
index 0000000..796f8ac
--- /dev/null
+++ b/core/java/com/android/internal/util/ProgressReporter.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IProgressListener;
+import android.os.RemoteException;
+import android.util.MathUtils;
+
+/**
+ * Tracks and reports progress of a single task to a {@link IProgressListener}.
+ * The reported progress of a task ranges from 0-100, but the task can be
+ * segmented into smaller pieces using {@link #startSegment(int)} and
+ * {@link #endSegment(int[])}, and segments can be nested.
+ * <p>
+ * Here's an example in action; when finished the overall task progress will be
+ * at 60.
+ *
+ * <pre>
+ * prog.setProgress(20);
+ * {
+ *     final int restore = prog.startSegment(40);
+ *     for (int i = 0; i < N; i++) {
+ *         prog.setProgress(i, N);
+ *         ...
+ *     }
+ *     prog.endSegment(restore);
+ * }
+ * </pre>
+ *
+ * This class is not thread safe.
+ *
+ * @hide
+ */
+public class ProgressReporter {
+    public static final ProgressReporter NO_OP = new ProgressReporter(0, null);
+
+    private final int mId;
+    private final IProgressListener mListener;
+
+    private Bundle mExtras = new Bundle();
+
+    private int mProgress = 0;
+
+    /**
+     * Current segment range: first element is starting progress of this
+     * segment, second element is length of segment.
+     */
+    private int[] mSegmentRange = new int[] { 0, 100 };
+
+    /**
+     * Create a new task with the given identifier whose progress will be
+     * reported to the given listener.
+     */
+    public ProgressReporter(int id, @Nullable IProgressListener listener) {
+        mId = id;
+        mListener = listener;
+    }
+
+    /**
+     * Set the progress of the currently active segment.
+     *
+     * @param progress Segment progress between 0-100.
+     */
+    public void setProgress(int progress) {
+        setProgress(progress, 100, null);
+    }
+
+    /**
+     * Set the progress of the currently active segment.
+     *
+     * @param progress Segment progress between 0-100.
+     */
+    public void setProgress(int progress, @Nullable CharSequence title) {
+        setProgress(progress, 100, title);
+    }
+
+    /**
+     * Set the fractional progress of the currently active segment.
+     */
+    public void setProgress(int n, int m) {
+        setProgress(n, m, null);
+    }
+
+    /**
+     * Set the fractional progress of the currently active segment.
+     */
+    public void setProgress(int n, int m, @Nullable CharSequence title) {
+        mProgress = mSegmentRange[0]
+                + MathUtils.constrain((n * mSegmentRange[1]) / m, 0, mSegmentRange[1]);
+        if (title != null) {
+            mExtras.putCharSequence(Intent.EXTRA_TITLE, title);
+        }
+        notifyProgress(mId, mProgress, mExtras);
+    }
+
+    /**
+     * Start a new inner segment that will contribute the given range towards
+     * the currently active segment. You must pass the returned value to
+     * {@link #endSegment(int[])} when finished.
+     */
+    public int[] startSegment(int size) {
+        final int[] lastRange = mSegmentRange;
+        mSegmentRange = new int[] { mProgress, (size * mSegmentRange[1] / 100) };
+        return lastRange;
+    }
+
+    /**
+     * End the current segment.
+     */
+    public void endSegment(int[] lastRange) {
+        mProgress = mSegmentRange[0] + mSegmentRange[1];
+        mSegmentRange = lastRange;
+    }
+
+    int getProgress() {
+        return mProgress;
+    }
+
+    int[] getSegmentRange() {
+        return mSegmentRange;
+    }
+
+    /**
+     * Report this entire task as being finished.
+     */
+    public void finish() {
+        notifyFinished(mId, null);
+    }
+
+    private void notifyProgress(int id, int progress, Bundle extras) {
+        if (mListener != null) {
+            try {
+                mListener.onProgress(id, progress, extras);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    public void notifyFinished(int id, Bundle extras) {
+        if (mListener != null) {
+            try {
+                mListener.onFinished(id, extras);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+}
diff --git a/core/java/com/android/internal/util/ScreenShapeHelper.java b/core/java/com/android/internal/util/ScreenShapeHelper.java
index 4a196f8..5f390be 100644
--- a/core/java/com/android/internal/util/ScreenShapeHelper.java
+++ b/core/java/com/android/internal/util/ScreenShapeHelper.java
@@ -1,27 +1,20 @@
 package com.android.internal.util;
 
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.os.Build;
 import android.os.SystemProperties;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
 import android.view.ViewRootImpl;
 
-import com.android.internal.R;
-
 /**
  * @hide
  */
 public class ScreenShapeHelper {
-    private static final boolean IS_EMULATOR = Build.HARDWARE.contains("goldfish");
-
     /**
      * Return the bottom pixel window outset of a window given its style attributes.
      * @return An outset dimension in pixels or 0 if no outset should be applied.
      */
     public static int getWindowOutsetBottomPx(Resources resources) {
-        if (IS_EMULATOR) {
+        if (Build.IS_EMULATOR) {
             return SystemProperties.getInt(ViewRootImpl.PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX, 0);
         } else {
             return resources.getInteger(com.android.internal.R.integer.config_windowOutsetBottom);
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index ab918c8..530e00c 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -111,6 +111,6 @@
     }
 
     @Override
-    public void requestAppKeyboardShortcuts(IResultReceiver receiver) {
+    public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
     }
 }
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index afa1554..6c1ebb4 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.view;
 
+import com.android.internal.annotations.GuardedBy;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Bundle;
@@ -25,6 +27,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.inputmethod.BaseInputConnection;
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.ExtractedTextRequest;
@@ -58,12 +61,17 @@
     private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
     private static final int DO_CLEAR_META_KEY_STATES = 130;
     private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
+    private static final int DO_REPORT_FINISH = 150;
 
-    @NonNull
-    private final WeakReference<InputConnection> mInputConnection;
+    @GuardedBy("mLock")
+    @Nullable
+    private InputConnection mInputConnection;
 
     private Looper mMainLooper;
     private Handler mH;
+    private Object mLock = new Object();
+    @GuardedBy("mLock")
+    private boolean mFinished = false;
 
     static class SomeArgs {
         Object arg1;
@@ -83,15 +91,23 @@
         }
     }
     
-    public IInputConnectionWrapper(Looper mainLooper, InputConnection conn) {
-        mInputConnection = new WeakReference<>(conn);
+    public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
+        mInputConnection = inputConnection;
         mMainLooper = mainLooper;
         mH = new MyHandler(mMainLooper);
     }
 
     @Nullable
     public InputConnection getInputConnection() {
-        return mInputConnection.get();
+        synchronized (mLock) {
+            return mInputConnection;
+        }
+    }
+
+    protected boolean isFinished() {
+        synchronized (mLock) {
+            return mFinished;
+        }
     }
 
     abstract protected boolean isActive();
@@ -206,6 +222,10 @@
                 seq, callback));
     }
 
+    public void reportFinish() {
+        dispatchMessage(obtainMessage(DO_REPORT_FINISH));
+    }
+
     void dispatchMessage(Message msg) {
         // If we are calling this from the main thread, then we can call
         // right through.  Otherwise, we need to send the message to the
@@ -218,13 +238,13 @@
         
         mH.sendMessage(msg);
     }
-    
+
     void executeMessage(Message msg) {
         switch (msg.what) {
             case DO_GET_TEXT_AFTER_CURSOR: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 try {
-                    InputConnection ic = mInputConnection.get();
+                    InputConnection ic = getInputConnection();
                     if (ic == null || !isActive()) {
                         Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
                         args.callback.setTextAfterCursor(null, args.seq);
@@ -240,7 +260,7 @@
             case DO_GET_TEXT_BEFORE_CURSOR: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 try {
-                    InputConnection ic = mInputConnection.get();
+                    InputConnection ic = getInputConnection();
                     if (ic == null || !isActive()) {
                         Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
                         args.callback.setTextBeforeCursor(null, args.seq);
@@ -256,7 +276,7 @@
             case DO_GET_SELECTED_TEXT: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 try {
-                    InputConnection ic = mInputConnection.get();
+                    InputConnection ic = getInputConnection();
                     if (ic == null || !isActive()) {
                         Log.w(TAG, "getSelectedText on inactive InputConnection");
                         args.callback.setSelectedText(null, args.seq);
@@ -272,7 +292,7 @@
             case DO_GET_CURSOR_CAPS_MODE: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 try {
-                    InputConnection ic = mInputConnection.get();
+                    InputConnection ic = getInputConnection();
                     if (ic == null || !isActive()) {
                         Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
                         args.callback.setCursorCapsMode(0, args.seq);
@@ -288,7 +308,7 @@
             case DO_GET_EXTRACTED_TEXT: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 try {
-                    InputConnection ic = mInputConnection.get();
+                    InputConnection ic = getInputConnection();
                     if (ic == null || !isActive()) {
                         Log.w(TAG, "getExtractedText on inactive InputConnection");
                         args.callback.setExtractedText(null, args.seq);
@@ -302,7 +322,7 @@
                 return;
             }
             case DO_COMMIT_TEXT: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "commitText on inactive InputConnection");
                     return;
@@ -312,7 +332,7 @@
                 return;
             }
             case DO_SET_SELECTION: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "setSelection on inactive InputConnection");
                     return;
@@ -321,7 +341,7 @@
                 return;
             }
             case DO_PERFORM_EDITOR_ACTION: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "performEditorAction on inactive InputConnection");
                     return;
@@ -330,7 +350,7 @@
                 return;
             }
             case DO_PERFORM_CONTEXT_MENU_ACTION: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "performContextMenuAction on inactive InputConnection");
                     return;
@@ -339,7 +359,7 @@
                 return;
             }
             case DO_COMMIT_COMPLETION: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "commitCompletion on inactive InputConnection");
                     return;
@@ -348,7 +368,7 @@
                 return;
             }
             case DO_COMMIT_CORRECTION: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "commitCorrection on inactive InputConnection");
                     return;
@@ -357,7 +377,7 @@
                 return;
             }
             case DO_SET_COMPOSING_TEXT: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "setComposingText on inactive InputConnection");
                     return;
@@ -367,7 +387,7 @@
                 return;
             }
             case DO_SET_COMPOSING_REGION: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "setComposingRegion on inactive InputConnection");
                     return;
@@ -376,7 +396,7 @@
                 return;
             }
             case DO_FINISH_COMPOSING_TEXT: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 // Note we do NOT check isActive() here, because this is safe
                 // for an IME to call at any time, and we need to allow it
                 // through to clean up our state after the IME has switched to
@@ -389,7 +409,7 @@
                 return;
             }
             case DO_SEND_KEY_EVENT: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "sendKeyEvent on inactive InputConnection");
                     return;
@@ -399,7 +419,7 @@
                 return;
             }
             case DO_CLEAR_META_KEY_STATES: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
                     return;
@@ -408,7 +428,7 @@
                 return;
             }
             case DO_DELETE_SURROUNDING_TEXT: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
                     return;
@@ -417,7 +437,7 @@
                 return;
             }
             case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
                     return;
@@ -426,7 +446,7 @@
                 return;
             }
             case DO_BEGIN_BATCH_EDIT: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "beginBatchEdit on inactive InputConnection");
                     return;
@@ -435,7 +455,7 @@
                 return;
             }
             case DO_END_BATCH_EDIT: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "endBatchEdit on inactive InputConnection");
                     return;
@@ -444,7 +464,7 @@
                 return;
             }
             case DO_REPORT_FULLSCREEN_MODE: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null) {
                     Log.w(TAG, "reportFullscreenMode on inexistent InputConnection");
                     return;
@@ -455,7 +475,7 @@
                 return;
             }
             case DO_PERFORM_PRIVATE_COMMAND: {
-                InputConnection ic = mInputConnection.get();
+                InputConnection ic = getInputConnection();
                 if (ic == null || !isActive()) {
                     Log.w(TAG, "performPrivateCommand on inactive InputConnection");
                     return;
@@ -468,7 +488,7 @@
             case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
                 SomeArgs args = (SomeArgs)msg.obj;
                 try {
-                    InputConnection ic = mInputConnection.get();
+                    InputConnection ic = getInputConnection();
                     if (ic == null || !isActive()) {
                         Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
                         args.callback.setRequestUpdateCursorAnchorInfoResult(false, args.seq);
@@ -481,6 +501,37 @@
                 }
                 return;
             }
+            case DO_REPORT_FINISH: {
+                // Note that we do not need to worry about race condition here, because 1) mFinished
+                // is updated only inside this block, and 2) the code here is running on a Handler
+                // hence we assume multiple DO_REPORT_FINISH messages will not be handled at the
+                // same time.
+                if (isFinished()) {
+                    return;
+                }
+                try {
+                    InputConnection ic = getInputConnection();
+                    // Note we do NOT check isActive() here, because this is safe
+                    // for an IME to call at any time, and we need to allow it
+                    // through to clean up our state after the IME has switched to
+                    // another client.
+                    if (ic == null) {
+                        return;
+                    }
+                    ic.finishComposingText();
+                    // TODO: Make reportFinish() public method of InputConnection to remove this
+                    // check.
+                    if (ic instanceof BaseInputConnection) {
+                        ((BaseInputConnection) ic).reportFinish();
+                    }
+                } finally {
+                    synchronized (mLock) {
+                        mInputConnection = null;
+                        mFinished = true;
+                    }
+                }
+                return;
+            }
         }
         Log.w(TAG, "Unhandled message code: " + msg.what);
     }
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index f211ff2..a96b5a0 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -83,8 +83,11 @@
         return false;
     }
 
+    /**
+     * @hide
+     */
     @Override
-    protected void reportFinish() {
+    public void reportFinish() {
         super.reportFinish();
 
         synchronized(this) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c685b0c..c6112d9 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -193,9 +193,9 @@
     $(TOP)/system/media/camera/include \
     $(TOP)/system/netd/include \
     external/pdfium/core/include/fpdfapi \
-    external/pdfium/core/include/fpdfdoc \
     external/pdfium/fpdfsdk/include \
     external/pdfium/public \
+    external/pdfium \
     external/skia/include/private \
     external/skia/src/core \
     external/skia/src/effects \
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 1ead618..528541d 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -723,6 +723,7 @@
         // Make sure that the recycled bitmap has the correct alpha type.
         mRecycledBitmap->setAlphaType(bitmap->alphaType());
 
+        bitmap->notifyPixelsChanged();
         bitmap->lockPixels();
         mNeedsCopy = false;
 
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 2998c99..ab393f2 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -232,12 +232,6 @@
         obj->addPath(*src, *matrix);
     }
 
-    static void offset__FFPath(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy, jlong dstHandle) {
-        SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
-        SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
-        obj->offset(dx, dy, dst);
-    }
-
     static void offset__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) {
         SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
         obj->offset(dx, dy);
@@ -508,7 +502,6 @@
     {"native_addPath","(JJFF)V", (void*) SkPathGlue::addPath__PathFF},
     {"native_addPath","(JJ)V", (void*) SkPathGlue::addPath__Path},
     {"native_addPath","(JJJ)V", (void*) SkPathGlue::addPath__PathMatrix},
-    {"native_offset","(JFFJ)V", (void*) SkPathGlue::offset__FFPath},
     {"native_offset","(JFF)V", (void*) SkPathGlue::offset__FF},
     {"native_setLastPoint","(JFF)V", (void*) SkPathGlue::setLastPoint},
     {"native_transform","(JJJ)V", (void*) SkPathGlue::transform__MatrixPath},
diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp
index 0177635..2c840bd 100644
--- a/core/jni/android/graphics/pdf/PdfEditor.cpp
+++ b/core/jni/android/graphics/pdf/PdfEditor.cpp
@@ -196,7 +196,7 @@
         return;
     }
 
-    CFX_AffineMatrix matrix;
+    CFX_Matrix matrix;
 
     SkMatrix* skTransform = reinterpret_cast<SkMatrix*>(transformPtr);
 
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index 6ddfacf..27f3493 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -205,11 +205,10 @@
     clip.bottom = destBottom;
     fxgeDevice->SetClip_Rect(&clip);
 
-    CPDF_RenderContext* pageContext = new CPDF_RenderContext;
+    CPDF_RenderContext* pageContext = new CPDF_RenderContext(pPage);
     pContext->m_pContext = pageContext;
-    pageContext->Create(pPage);
 
-    CFX_AffineMatrix matrix;
+    CFX_Matrix matrix;
     if (!transform) {
         pPage->GetDisplayMatrix(matrix, destLeft, destTop, destRight - destLeft,
                 destBottom - destTop, 0);
@@ -232,8 +231,8 @@
     }
     pageContext->AppendObjectList(pPage, &matrix);
 
-    pContext->m_pRenderer = new CPDF_ProgressiveRenderer;
-    pContext->m_pRenderer->Start(pageContext, fxgeDevice, renderOptions, NULL);
+    pContext->m_pRenderer = new CPDF_ProgressiveRenderer(pageContext, fxgeDevice, renderOptions);
+    pContext->m_pRenderer->Start(NULL);
 
     fxgeDevice->RestoreState();
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 60f05448..8abb7e2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -706,7 +706,9 @@
         android:description="@string/permgroupdesc_phone"
         android:priority="500" />
 
-    <!-- Allows read only access to phone state.
+    <!-- Allows read only access to phone state, including the phone number of the device,
+         current cellular network information, the status of any ongoing calls, and a list of any
+         {@link android.telecom.PhoneAccount}s registered on the device.
          <p class="note"><strong>Note:</strong> If <em>both</em> your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
          minSdkVersion}</a> and <a
diff --git a/core/res/res/layout-w600dp/preference_list_content_single.xml b/core/res/res/layout-sw600dp/preference_list_content_single.xml
similarity index 88%
rename from core/res/res/layout-w600dp/preference_list_content_single.xml
rename to core/res/res/layout-sw600dp/preference_list_content_single.xml
index d2fa5b9..88b1aa8 100644
--- a/core/res/res/layout-w600dp/preference_list_content_single.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content_single.xml
@@ -33,20 +33,22 @@
             style="?attr/preferencePanelStyle"
             android:orientation="vertical"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:paddingStart="32dip"
-            android:paddingEnd="32dip"
-            android:paddingTop="32dip"
-            android:paddingBottom="32dip" >
+            android:layout_height="match_parent">
 
-            <ListView android:id="@android:id/list"
+            <ListView
+                android:id="@android:id/list"
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
-                android:scrollbarAlwaysDrawVerticalTrack="true" />
+                android:scrollbarAlwaysDrawVerticalTrack="true"
+                android:paddingStart="32dip"
+                android:paddingEnd="32dip"
+                android:paddingTop="32dip"
+                android:paddingBottom="32dip"
+                android:clipToPadding="false"/>
 
             <FrameLayout android:id="@+id/list_footer"
                     android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 809e525..ba6d30a 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -51,7 +51,7 @@
         <LinearLayout
             android:id="@+id/media_actions"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             android:layout_gravity="bottom|end"
             android:layout_marginStart="10dp"
             android:layout_marginBottom="12dp"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index be140a5..1f958b4 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Meer opsies"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s - %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s-%2$s%3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Interne gedeelde berging"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kaart"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g>-SD-kaart"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-datastokkie"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a87090a..2623053 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ተጨማሪ አማራጮች"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s፣ %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s፣ %2$s፣ %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"የውስጥ የተጋራ ማከማቻ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD ካርድ"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> ኤስዲ ካርድ"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"የዩኤስቢ አንጻፊ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 01d47cf..b828197 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1260,8 +1260,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"المزيد من الخيارات"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s، %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s، %2$s، %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"السعة التخزينية المشتركة الداخلية"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"‏بطاقة SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"‏بطاقة SD من <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"‏محرك أقراص USB"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 58d81b2..25a979b 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Əlavə seçimlər"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Daxili paylaşılan yaddaş"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kart"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB drayv"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index b8c6fd3..3eff6f3 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1233,8 +1233,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Još opcija"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Unutrašnji deljeni memorijski prostor"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB disk"</string>
diff --git a/core/res/res/values-be-rBY/strings.xml b/core/res/res/values-be-rBY/strings.xml
index 502e1e9..7b85628 100644
--- a/core/res/res/values-be-rBY/strings.xml
+++ b/core/res/res/values-be-rBY/strings.xml
@@ -1242,8 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Больш налад"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Унутранае абагуленае сховішча"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD-карта <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-дыск"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 62d0d372..4515e80 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Още опции"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"„%1$s“ – %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"„%1$s“, „%2$s“ – %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Вътрешно споделено хранилище"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD карта"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD карта от <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB устройство"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index cbe8eca..03faf2f 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -28,11 +28,11 @@
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> দিন"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘন্টা"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘন্টা"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ঘন্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
+    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘণ্টা"</string>
+    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> দিন <xliff:g id="HOURS">%2$d</xliff:g> ঘণ্টা"</string>
+    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা"</string>
+    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
+    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> ঘণ্টা <xliff:g id="MINUTES">%2$d</xliff:g> মিনিট"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
     <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট"</string>
     <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> মিনিট <xliff:g id="SECONDS">%2$d</xliff:g> সেকেন্ড"</string>
@@ -829,8 +829,8 @@
     <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g> এ"</string>
     <string name="day" msgid="8144195776058119424">"দিন"</string>
     <string name="days" msgid="4774547661021344602">"দিন"</string>
-    <string name="hour" msgid="2126771916426189481">"ঘন্টা"</string>
-    <string name="hours" msgid="894424005266852993">"ঘন্টা"</string>
+    <string name="hour" msgid="2126771916426189481">"ঘণ্টা"</string>
+    <string name="hours" msgid="894424005266852993">"ঘণ্টা"</string>
     <string name="minute" msgid="9148878657703769868">"মি"</string>
     <string name="minutes" msgid="5646001005827034509">"মিনিট"</string>
     <string name="second" msgid="3184235808021478">"সেকেন্ড"</string>
@@ -848,8 +848,8 @@
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> মিনিট</item>
     </plurals>
     <plurals name="duration_hours" formatted="false" msgid="6826233369186668274">
-      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ঘন্টা</item>
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ঘন্টা</item>
+      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ঘণ্টা</item>
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ঘণ্টা</item>
     </plurals>
     <string name="VideoView_error_title" msgid="3534509135438353077">"ভিডিও সমস্যা"</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"এই ভিডিওটি এই ডিভাইসে স্ট্রিমিং করার জন্য বৈধ নয়৷"</string>
@@ -869,7 +869,7 @@
     <string name="paste_as_plain_text" msgid="5427792741908010675">"প্লেইন টেক্সট হিসাবে আটকান"</string>
     <string name="replace" msgid="5781686059063148930">"প্রতিস্থাপন করুন..."</string>
     <string name="delete" msgid="6098684844021697789">"মুছুন"</string>
-    <string name="copyUrl" msgid="2538211579596067402">"URL অনুলিপি করুন"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"URL কপি করুন"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"পাঠ্য নির্বাচন করুন"</string>
     <string name="undo" msgid="7905788502491742328">"পূর্বাবস্থায় ফিরুন"</string>
     <string name="redo" msgid="7759464876566803888">"পুনরায় করুন"</string>
@@ -1192,8 +1192,8 @@
     <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"বাড়ানোর জন্য উপরের দিকে এবং কমানোর জন্য নীচের দিকে স্লাইড করুন৷"</string>
     <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"মিনিট বাড়ান"</string>
     <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"মিনিট কমান"</string>
-    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"ঘন্টা বাড়ান"</string>
-    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"ঘন্টা কমান"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"ঘণ্টা বাড়ান"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"ঘণ্টা কমান"</string>
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM সেট করুন"</string>
     <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM সেট করুন"</string>
     <string name="date_picker_increment_month_button" msgid="5369998479067934110">"মাস বাড়ান"</string>
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"আরো বিকল্প"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"অভ্যন্তরীণ শেয়ার করা সঞ্চয়স্থান"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD কার্ড"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD কার্ড"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ড্রাইভ"</string>
@@ -1453,9 +1452,9 @@
     <string name="immersive_cling_description" msgid="3482371193207536040">"প্রস্থান করতে উপর থেকে নীচের দিকে সোয়াইপ করুন"</string>
     <string name="immersive_cling_positive" msgid="5016839404568297683">"বুঝেছি"</string>
     <string name="done_label" msgid="2093726099505892398">"সম্পন্ন হয়েছে"</string>
-    <string name="hour_picker_description" msgid="6698199186859736512">"বৃত্তাকার ঘন্টা নির্বাচকের স্লাইডার"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"বৃত্তাকার ঘণ্টা নির্বাচকের স্লাইডার"</string>
     <string name="minute_picker_description" msgid="8606010966873791190">"বৃত্তাকার মিনিট নির্বাচকের স্লাইডার"</string>
-    <string name="select_hours" msgid="6043079511766008245">"ঘন্টা নির্বাচন করুন"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ঘণ্টা নির্বাচন করুন"</string>
     <string name="select_minutes" msgid="3974345615920336087">"মিনিট নির্বাচন করুন"</string>
     <string name="select_day" msgid="7774759604701773332">"মাস এবং দিন নির্বাচন করুন"</string>
     <string name="select_year" msgid="7952052866994196170">"বছর নির্বাচন করুন"</string>
diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml
index 6e7d8d2..7e9f44f 100644
--- a/core/res/res/values-bs-rBA/strings.xml
+++ b/core/res/res/values-bs-rBA/strings.xml
@@ -1233,8 +1233,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Interno dijeljena pohrana"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB disk"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 9044a1a..e59c936 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Més opcions"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Emmagatzematge intern compartit"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Targeta SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Targeta SD de: <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unitat USB"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 8875ead..391b012 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere valgmuligheder"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Intern delt lagerplads"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kort fra <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-drev"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a1183e9..d95bdda 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Weitere Optionen"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s. %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s. %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Interner gemeinsamer Speicher"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-Karte"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD-Karte von <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-Speichergerät"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4e5f8fb..ce0805f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Περισσότερες επιλογές"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Εσωτερικός κοινόχρηστος αποθηκευτικός χώρος"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Κάρτα SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Κάρτα SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Μονάδα USB"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 2484fe5..27cd9d2 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Almacenamiento interno compartido"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Tarjeta SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Tarjeta SD de <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unidad USB"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index ed5db6c..8b8f29f 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Aukera gehiago"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Barneko biltegiratze partekatua"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD txartela"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD txartela"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB unitatea"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b143038..e67e058 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"سایر گزینه‌ها"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"‎%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"‎%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"حافظه داخلی مشترک"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"‏کارت SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"‏کارت SD ‏<xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"‏درایو USB"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8bb613e..b1ad7e7 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Lisää asetuksia"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Sisäinen jaettu tallennustila"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kortti"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kortti: <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-asema"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 3375e185..09993ac 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Stockage interne partagé"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Carte SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Carte mémoire SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Clé USB"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 741d0e1..30ff9fb 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Espace de stockage interne partagé"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Carte SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Carte SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Clé USB"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index be83dab..0d479a5 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Máis opcións"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Almacenamento compartido interno"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Tarxeta SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Tarxeta SD de <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unidade USB"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 2ce73f4..bc74c9d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1233,8 +1233,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Unutarnja dijeljena pohrana"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB pogon"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 8921e88..030975e 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Ավելի շատ ընտրանքներ"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Համօգտագործվող ներքին հիշողություն"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD քարտ"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD քարտ <xliff:g id="MANUFACTURER">%s</xliff:g>-ից"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB սարքավար"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index e7c706d..819ea80 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Opsi lainnya"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Penyimpanan bersama internal"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kartu SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Kartu SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Drive USB"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 5edb125..91624e75 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Fleiri valkostir"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Innbyggð samnýtt geymsla"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kort frá <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-drif"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 73775a0..9937e0d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Archivio condiviso interno"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Scheda SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Scheda SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unità USB"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index b06434e..443c1be 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1242,8 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"אפשרויות נוספות"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"‏%1$s‏, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"‏%1$s‏, %2$s‏, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"אחסון משותף פנימי"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"‏כרטיס SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"‏כרטיס SD של <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"‏כונן USB"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 14d64b0..e81beb3 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"その他のオプション"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s、%2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s、%2$s、%3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"内部共有ストレージ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SDカード"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g>製SDカード"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USBドライブ"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 92e57b7..3e463f1c 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"მეტი ვარიანტები"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"შიდა გაზიარებული მეხსიერება"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD ბარათი"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD ბარათი"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB დისკი"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 85621ed..342db02 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Басқа опциялар"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Ішкі ортақ қойма"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD картасы"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD картасы"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB дискі"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index e9be6b6..fdee3aa 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1226,8 +1226,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ជម្រើស​ច្រើន​ទៀត"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"ឧបករណ៍ផ្ទុកដែលចែករំលែកខាងក្នុង"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"កាត​អេសឌី"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"កាត SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"ឧបករណ៍ផ្ទុក USB"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 2e04419..b31b2bb 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"ಆಂತರಿಕವಾಗಿ ಹಂಚಲಾದ ಸಂಗ್ರಹಣೆ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD ಕಾರ್ಡ್"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD ಕಾರ್ಡ್"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ಡ್ರೈವ್"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index b61df80..51418d9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"옵션 더보기"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"내부 공유 저장공간"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD 카드"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 카드"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB 드라이브"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 55b2b7c..32f3d9a 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -900,8 +900,8 @@
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s менен түзөтүү"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"Төмөнкү менен бөлүшүү"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"%1$s менен бөлүшүү"</string>
-    <string name="whichSendToApplication" msgid="8272422260066642057">"Колдонуп жөнөтүү"</string>
-    <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s колдонуп жөнөтүү"</string>
+    <string name="whichSendToApplication" msgid="8272422260066642057">"Колдонмо тандаңыз"</string>
+    <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s аркылуу жөнөтүү"</string>
     <string name="whichHomeApplication" msgid="4307587691506919691">"Башкы бет колдонмосун тандаңыз"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Башкы бет колдонмосу катары %1$s пайдалануу"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Бул аракет үчүн демейки боюнча колдонулсун."</string>
@@ -1225,8 +1225,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Дагы параметрлер"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Бөлүшүлгөн ички сактагыч"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD карта"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB түзмөк"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 5d1c37e..94fb2db 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ໂຕເລືອກອື່ນ"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນພາຍໃນ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> ແຜ່ນ SD"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ດ​ຣ້າຍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1460b9b..c4c4fa2 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1242,8 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Daugiau parinkčių"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Vidinė bendroji atmintis"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kortelė"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"„<xliff:g id="MANUFACTURER">%s</xliff:g>“ SD kortelė"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Atmintukas"</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index c4ef82c..d9dae7a 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1226,8 +1226,7 @@
     <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
     <skip />
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Внатрешно заедничко место за складирање"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"СД картичка"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> СД-картичка"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"УСБ-меморија"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 9b96501..16ededc 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"കൂടുതൽ‍ ഓപ്‌ഷനുകള്‍"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"പങ്കിട്ട ആന്തരിക സ്റ്റോറേജ്"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD കാർഡ്"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD കാർഡ്"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ഡ്രൈവ്"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index ef34b46..0f31862 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Нэмэлт сонголтууд"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Дотоод хуваалцсан санах ой"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD карт"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD карт"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB диск"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 7baa543..9a35efd 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"अधिक पर्याय"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"अंतर्गत सामायिक केलेला संचय"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD कार्ड"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ड्राइव्‍ह"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index c2e3bfe..7c8ce0f 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Lagi pilihan"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Storan kongsi dalaman"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kad SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Kad SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Pemacu USB"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 459eccd..b6f3c37 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1230,8 +1230,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"थप विकल्पहरू"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"साझेदारी गरिएको आन्तरिक भण्डारण"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD कार्ड"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ड्राइभ"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index f74b93c..8de9102 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ਹੋਰ ਚੋਣਾਂ"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"ਅੰਦਰੂਨੀ ਸਾਂਝੀ ਕੀਤੀ ਗਈ ਸਟੋਰੇਜ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD ਕਾਰਡ"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD ਕਾਰਡ"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ਡ੍ਰਾਇਵ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6e4091a..f20e97d 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1242,8 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Więcej opcji"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Wewnętrzna pamięć współdzielona"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Karta SD (<xliff:g id="MANUFACTURER">%s</xliff:g>)"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Dysk USB"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 62ee01c..2212f9f 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Armazenamento interno compartilhado"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Cartão SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Drive USB"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 331cd9d..6cb94c37 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Armazenamento interno partilhado"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Cartão SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unidade USB"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 62ee01c..2212f9f 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Armazenamento interno compartilhado"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Cartão SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Drive USB"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index dd4faad..31ec3a0 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1233,8 +1233,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opțiuni"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Memorie internă comună"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Card SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Card SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Unitate USB"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 4d618ac..5a79523 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1242,8 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Ещё"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Внутренний общий накопитель"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD-карта <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-накопитель"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 5dbb922..4f34cd0 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1226,8 +1226,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"තවත් විකල්ප"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"අභ්‍යන්තර බෙදා ගත් ගබඩාව"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD පත"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD කාඩ්පත"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB ධාවකය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 75a2129..4ba64b1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1242,8 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Viac možností"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Interné zdieľané úložisko"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD karta"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD karta <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Disk USB"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 579880a..eb3d4e0 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1242,8 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Več možnosti"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Notranja shramba v skupni rabi"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kartica SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Kartica SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Pogon USB"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index b39f297..94258e2 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Opsione të tjera"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Hapësira ruajtëse e brendshme e ndarë"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Karta SD nga <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-ja"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 74fc273..bfc22e4 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1233,8 +1233,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Још опција"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Унутрашњи дељени меморијски простор"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD картица"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD картица"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB диск"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 610fa07..3f2a4a3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Fler alternativ"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Delat internt lagringsutrymme"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"SD-kort (<xliff:g id="MANUFACTURER">%s</xliff:g>)"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB-enhet"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3d4bc60d..2e1a7a4 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1226,8 +1226,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Chaguo zaidi"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Hifadhi ya ndani inayoshirikiwa"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kadi ya SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Kadi ya SD iliyotengenezwa na <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Hifadhi ya USB"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 9411f5b..b34caed 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"மேலும் விருப்பங்கள்"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"பகிர்ந்த சேமிப்பகம் (அகம்)"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD கார்டு"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD கார்டு"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB டிரைவ்"</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index 58d3d91..c0716e9 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -26,12 +26,4 @@
 
     <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
     <string translatable="false" name="config_defaultPictureInPictureBounds">"1328 54 1808 324"</string>
-
-    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, when the PIP
-         is located in center. -->
-    <string translatable="false" name="config_centeredPictureInPictureBounds">"596 280 1324 690"</string>
-
-    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
-         when the PIP is shown with Recents. -->
-    <string translatable="false" name="config_pictureInPictureBoundsInRecents">"1484 96 1804 276"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 353da8a..d0b6f43 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ตัวเลือกเพิ่มเติม"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"ที่จัดเก็บข้อมูลที่ใช้ร่วมกันภายใน"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"การ์ด SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"การ์ด SD ของ <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"ไดรฟ์ USB"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 41ada1c..698ae61 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Higit pang mga pagpipilian"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Internal na nakabahaging storage"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD card"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB drive"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 3a04463..52c32e7 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Diğer seçenekler"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Dahili olarak paylaşılan depolama alanı"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartı"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB sürücü"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 565cdd9..41a1e82 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"مزید اختیارات"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"اندرونی اشتراک کردہ اسٹوریج"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"‏SD کارڈ"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"‏<xliff:g id="MANUFACTURER">%s</xliff:g> SD کارڈ"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"‏USB ڈرائیو"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 1a81245..e3b9e9a 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -900,7 +900,7 @@
     <string name="whichSendApplication" msgid="6902512414057341668">"Ulashish…"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"“%1$s” orqali ulashish"</string>
     <string name="whichSendToApplication" msgid="8272422260066642057">"Ilovani tanlang"</string>
-    <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s yordamida yuborish"</string>
+    <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"%1$s orqali yuborish"</string>
     <string name="whichHomeApplication" msgid="4307587691506919691">"Bosh ilovani tanlash"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"%1$s: Bosh ilova sifatida foydalanish"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Ushbu amaldan standart sifatida foydalanish"</string>
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Ko‘proq sozlamalar"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Ichki umumiy xotira"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD karta"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartasi"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB xotira"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7302f7a..76743f2 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Tùy chọn khác"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Bộ nhớ trong dùng chung"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Thẻ SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"Thẻ SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Ổ USB"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4c90e1c..3b0c075 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -899,7 +899,7 @@
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"使用%1$s编辑"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"分享方式"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"使用%1$s分享"</string>
-    <string name="whichSendToApplication" msgid="8272422260066642057">"通过以下应用发送:"</string>
+    <string name="whichSendToApplication" msgid="8272422260066642057">"通过以下应用发送"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"通过1$s发送"</string>
     <string name="whichHomeApplication" msgid="4307587691506919691">"选择主屏幕应用"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"将“%1$s”设为主屏幕应用"</string>
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"更多选项"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s:%2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s - %2$s:%3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"内部共享的存储空间"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD卡"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"U 盘"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a782d40..6e62d1c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"更多選項"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s:%2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s - %2$s:%3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"內部共用儲存空間"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD 卡"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB 隨身碟"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 23d72dc0..ddd486b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1224,8 +1224,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Izinketho ezingaphezulu"</string>
     <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string>
-    <!-- no translation found for storage_internal (3570990907910199483) -->
-    <skip />
+    <string name="storage_internal" msgid="3570990907910199483">"Isitoreji esabiwe sangaphakathi"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Ikhadi le-SD"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> ikhadi le-SD"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"Idrayivu ye-USB"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 5716823..d1c0895 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2262,13 +2262,20 @@
         <!-- Where to initially position the activity inside the available space. Uses constants
              defined in {@link android.view.Gravity}. -->
         <attr name="gravity" />
+        <!-- Minimal width of the activity.
+
+         <p><strong>NOTE:</strong> A task's root activity value is applied to all additional
+         activities launched in the task. That is if the root activity of a task set minimal width,
+         then the system will set the same minimal width on all other activities in the task. It
+         will also ignore any other minimal width attributes of non-root activities. -->
+        <attr name="minimalWidth" format="dimension" />
         <!-- Minimal height of the activity.
 
          <p><strong>NOTE:</strong> A task's root activity value is applied to all additional
-         activities launched in the task. That is if the root activity of a task set minimal size,
-         then the system will set the same minimal size on all other activities in the task. It will
-         also ignore any other minimal size attributes of non-root activities. -->
-        <attr name="minimalSize" format="dimension" />
+         activities launched in the task. That is if the root activity of a task set minimal height,
+         then the system will set the same minimal height on all other activities in the task. It
+         will also ignore any other minimal height attributes of non-root activities. -->
+        <attr name="minimalHeight" format="dimension" />
     </declare-styleable>
 
 </resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 48aa440..bddd225 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -180,4 +180,7 @@
 
     <!-- Status bar color for semi transparent mode. -->
     <color name="system_bar_background_semi_transparent">#66000000</color> <!-- 40% black -->
+
+    <color name="resize_shadow_start_color">#2a000000</color>
+    <color name="resize_shadow_end_color">#00000000</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 01b2c47..6ecaa1f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2462,14 +2462,6 @@
     <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. -->
     <string translatable="false" name="config_defaultPictureInPictureBounds">"0 0 100 100"</string>
 
-    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows, when the PIP
-         is located in center. -->
-    <string translatable="false" name="config_centeredPictureInPictureBounds">"0 0 300 300"</string>
-
-    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
-         when the PIP is shown with Recents. -->
-    <string translatable="false" name="config_pictureInPictureBoundsInRecents">"0 0 100 100"</string>
-
     <!-- Controls the snap mode for the docked stack divider
              0 - 3 snap targets: left/top has 16:9 ratio, 1:1, and right/bottom has 16:9 ratio
              1 - 3 snap targets: fixed ratio, 1:1, (1 - fixed ratio)
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 081d613..71d9a1f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -22,6 +22,8 @@
     <dimen name="thumbnail_width">192dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
     <dimen name="thumbnail_height">192dp</dimen>
+    <!-- The amount to scale a fullscreen screenshot thumbnail. -->
+    <item name="thumbnail_fullscreen_scale" type="fraction">60%</item>
     <!-- The standard size (both width and height) of an application icon that
          will be displayed in the app launcher and elsewhere. -->
     <dimen name="app_icon_size">48dip</dimen>
@@ -450,4 +452,6 @@
     <item type="dimen" name="aerr_padding_list_top">15dp</item>
 
     <item type="fraction" name="docked_stack_divider_fixed_ratio">34.15%</item>
+
+    <dimen name="resize_shadow_size">5dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7b85c7e..ed7b4d8 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2664,7 +2664,8 @@
     <public type="attr" name="subMenuArrow" />
     <public type="attr" name="defaultWidth" />
     <public type="attr" name="defaultHeight" />
-    <public type="attr" name="minimalSize" />
+    <public type="attr" name="minimalWidth" />
+    <public type="attr" name="minimalHeight" />
     <public type="attr" name="resizeableActivity" />
     <public type="attr" name="supportsPictureInPicture" />
     <public type="attr" name="titleMargin" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 74ce753..e94a91d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2904,7 +2904,9 @@
     <string name="dlg_ok">OK</string>
 
     <!-- USB_PREFERENCES: Notification for when the user connected to the charger only.  This is the title -->
-    <string name="usb_charging_notification_title">USB for charging</string>
+    <string name="usb_charging_notification_title">USB charging this device</string>
+    <!-- USB_PREFERENCES: Notification for when the user connects the phone to supply power to attached device.  This is the title -->
+    <string name="usb_supplying_notification_title">USB supplying power to attached device</string>
     <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MTP mode.  This is the title -->
     <string name="usb_mtp_notification_title">USB for file transfer</string>
     <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in PTP mode.  This is the title -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ce7d80b..6526571 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -308,8 +308,6 @@
   <java-symbol type="bool" name="config_guestUserEphemeral" />
   <java-symbol type="bool" name="config_localDisplaysMirrorContent" />
   <java-symbol type="string" name="config_defaultPictureInPictureBounds" />
-  <java-symbol type="string" name="config_centeredPictureInPictureBounds" />
-  <java-symbol type="string" name="config_pictureInPictureBoundsInRecents" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_factor" />
   <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
@@ -1513,6 +1511,10 @@
   <java-symbol type="dimen" name="docked_stack_minimize_thickness" />
   <java-symbol type="integer" name="config_dockedStackDividerSnapMode" />
   <java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" />
+  <java-symbol type="fraction" name="thumbnail_fullscreen_scale" />
+  <java-symbol type="dimen" name="resize_shadow_size" />
+  <java-symbol type="color" name="resize_shadow_start_color" />
+  <java-symbol type="color" name="resize_shadow_end_color" />
   <java-symbol type="dimen" name="navigation_bar_height" />
   <java-symbol type="dimen" name="navigation_bar_height_landscape" />
   <java-symbol type="dimen" name="navigation_bar_width" />
@@ -1861,6 +1863,7 @@
   <java-symbol type="string" name="usb_notification_message" />
   <java-symbol type="string" name="usb_ptp_notification_title" />
   <java-symbol type="string" name="usb_midi_notification_title" />
+  <java-symbol type="string" name="usb_supplying_notification_title" />
   <java-symbol type="string" name="vpn_text" />
   <java-symbol type="string" name="vpn_text_long" />
   <java-symbol type="string" name="vpn_title" />
diff --git a/core/tests/coretests/src/android/graphics/PathOffsetTest.java b/core/tests/coretests/src/android/graphics/PathOffsetTest.java
new file mode 100644
index 0000000..950f873
--- /dev/null
+++ b/core/tests/coretests/src/android/graphics/PathOffsetTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+
+import android.graphics.Bitmap.Config;
+import android.graphics.Path.Direction;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class PathOffsetTest {
+
+    private static final int SQUARE = 10;
+    private static final int WIDTH = 100;
+    private static final int HEIGHT = 100;
+    private static final int START_X = 10;
+    private static final int START_Y = 20;
+    private static final int OFFSET_X = 30;
+    private static final int OFFSET_Y = 40;
+
+    @Test
+    @SmallTest
+    public void testPathOffset() {
+        Path actualPath = new Path();
+        actualPath.addRect(START_X, START_Y, START_X + SQUARE, START_Y + SQUARE, Direction.CW);
+        assertTrue(actualPath.isSimplePath);
+        actualPath.offset(OFFSET_X, OFFSET_Y);
+        assertTrue(actualPath.isSimplePath);
+
+        Path expectedPath = new Path();
+        expectedPath.addRect(START_X + OFFSET_X, START_Y + OFFSET_Y, START_X + OFFSET_X + SQUARE,
+                START_Y + OFFSET_Y + SQUARE, Direction.CW);
+
+        assertPaths(actualPath, expectedPath);
+    }
+
+    @Test
+    @SmallTest
+    public void testPathOffsetWithDestination() {
+        Path initialPath = new Path();
+        initialPath.addRect(START_X, START_Y, START_X + SQUARE, START_Y + SQUARE, Direction.CW);
+        Path actualPath = new Path();
+        assertTrue(initialPath.isSimplePath);
+        assertTrue(actualPath.isSimplePath);
+        initialPath.offset(OFFSET_X, OFFSET_Y, actualPath);
+        assertTrue(actualPath.isSimplePath);
+
+        Path expectedPath = new Path();
+        expectedPath.addRect(START_X + OFFSET_X, START_Y + OFFSET_Y, START_X + OFFSET_X + SQUARE,
+                START_Y + OFFSET_Y + SQUARE, Direction.CW);
+
+        assertPaths(actualPath, expectedPath);
+    }
+
+    private static void assertPaths(Path actual, Path expected) {
+        Bitmap actualBitmap = drawAndGetBitmap(actual);
+        Bitmap expectedBitmap = drawAndGetBitmap(expected);
+        assertTrue(actualBitmap.sameAs(expectedBitmap));
+    }
+
+    private static Bitmap drawAndGetBitmap(Path path) {
+        Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Config.ARGB_8888);
+        bitmap.eraseColor(Color.BLACK);
+        Paint paint = new Paint();
+        paint.setColor(Color.RED);
+        Canvas canvas = new Canvas(bitmap);
+        canvas.drawPath(path, paint);
+        return bitmap;
+    }
+
+}
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index d554a50..cbed96c 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -20,6 +20,8 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.Layout.Alignment;
 import static android.text.Layout.Alignment.*;
+import android.text.TextPaint;
+import android.text.method.EditorState;
 import android.util.Log;
 
 import junit.framework.TestCase;
@@ -33,6 +35,10 @@
  * @Suppress
  */
 public class StaticLayoutTest extends TestCase {
+    private static final int DEFAULT_OUTER_WIDTH = 150;
+    private static final Alignment DEFAULT_ALIGN = Alignment.ALIGN_CENTER;
+    private static final float SPACE_MULTI = 1.0f;
+    private static final float SPACE_ADD = 0.0f;
 
     /**
      * Basic test showing expected behavior and relationship between font
@@ -321,4 +327,91 @@
         assertEquals(topPad, l.getTopPadding());
         assertEquals(botPad, l.getBottomPadding());
     }
+
+    private void moveCursorToRightCursorableOffset(EditorState state, TextPaint paint) {
+        assertEquals("The editor has selection", state.mSelectionStart, state.mSelectionEnd);
+        final Layout layout = builder().setText(state.mText.toString()).setPaint(paint).build();
+        final int newOffset = layout.getOffsetToRightOf(state.mSelectionStart);
+        state.mSelectionStart = state.mSelectionEnd = newOffset;
+    }
+
+    private void moveCursorToLeftCursorableOffset(EditorState state, TextPaint paint) {
+        assertEquals("The editor has selection", state.mSelectionStart, state.mSelectionEnd);
+        final Layout layout = builder().setText(state.mText.toString()).setPaint(paint).build();
+        final int newOffset = layout.getOffsetToLeftOf(state.mSelectionStart);
+        state.mSelectionStart = state.mSelectionEnd = newOffset;
+    }
+
+    /**
+     * Tests for keycap, variation selectors, flags are in CTS.
+     * See {@link android.text.cts.StaticLayoutTest}.
+     */
+    public void testEmojiOffset() {
+        EditorState state = new EditorState();
+        TextPaint paint = new TextPaint();
+
+        // Odd numbered regional indicator symbols.
+        // U+1F1E6 is REGIONAL INDICATOR SYMBOL LETTER A, U+1F1E8 is REGIONAL INDICATOR SYMBOL
+        // LETTER C.
+        state.setByString("| U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+1F1E6 U+1F1E8 | U+1F1E6 U+1F1E8 U+1F1E6");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 | U+1F1E6");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6 |");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6 |");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 | U+1F1E6");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("U+1F1E6 U+1F1E8 | U+1F1E6 U+1F1E8 U+1F1E6");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("| U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("| U+1F1E6 U+1F1E8 U+1F1E6 U+1F1E8 U+1F1E6");
+        moveCursorToLeftCursorableOffset(state, paint);
+
+        // Zero width sequence
+        final String zwjSequence = "U+1F468 U+200D U+2764 U+FE0F U+200D U+1F468";
+        state.setByString("| " + zwjSequence + " " + zwjSequence + " " + zwjSequence);
+        moveCursorToRightCursorableOffset(state, paint);
+        state.assertEquals(zwjSequence + " | " + zwjSequence + " " + zwjSequence);
+        moveCursorToRightCursorableOffset(state, paint);
+        state.assertEquals(zwjSequence + " " + zwjSequence + " | " + zwjSequence);
+        moveCursorToRightCursorableOffset(state, paint);
+        state.assertEquals(zwjSequence + " " + zwjSequence + " " + zwjSequence + " |");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.assertEquals(zwjSequence + " " + zwjSequence + " " + zwjSequence + " |");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.assertEquals(zwjSequence + " " + zwjSequence + " | " + zwjSequence);
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.assertEquals(zwjSequence + " | " + zwjSequence + " " + zwjSequence);
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.assertEquals("| " + zwjSequence + " " + zwjSequence + " " + zwjSequence);
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.assertEquals("| " + zwjSequence + " " + zwjSequence + " " + zwjSequence);
+        moveCursorToLeftCursorableOffset(state, paint);
+
+        // Emoji modifiers
+        // U+261D is WHITE UP POINTING INDEX, U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
+        state.setByString("| U+261D U+1F3FB U+261D U+1F3FB U+261D U+1F3FB");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+261D U+1F3FB | U+261D U+1F3FB U+261D U+1F3FB");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+261D U+1F3FB U+261D U+1F3FB | U+261D U+1F3FB");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+261D U+1F3FB U+261D U+1F3FB U+261D U+1F3FB |");
+        moveCursorToRightCursorableOffset(state, paint);
+        state.setByString("U+261D U+1F3FB U+261D U+1F3FB U+261D U+1F3FB |");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("U+261D U+1F3FB U+261D U+1F3FB | U+261D U+1F3FB");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("U+261D U+1F3FB | U+261D U+1F3FB U+261D U+1F3FB");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("| U+261D U+1F3FB U+261D U+1F3FB U+261D U+1F3FB");
+        moveCursorToLeftCursorableOffset(state, paint);
+        state.setByString("| U+261D U+1F3FB U+261D U+1F3FB U+261D U+1F3FB");
+        moveCursorToLeftCursorableOffset(state, paint);
+    }
 }
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 91d57e7..f779d6c 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -385,6 +385,51 @@
     }
 
     @SmallTest
+    public void testSelectionHandles_bidi() throws Exception {
+        final String text = "abc \u0621\u0622\u0623 def";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(replaceText(text));
+
+        assertNoSelectionHandles();
+
+        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0622')));
+
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .check(matches(isDisplayed()));
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .check(matches(isDisplayed()));
+
+        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
+        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('a')));
+        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0623') + 1,
+                        false));
+        onView(withId(R.id.textview)).check(hasSelection("\u0623"));
+
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u0621'),
+                        false));
+        onView(withId(R.id.textview)).check(hasSelection("\u0621\u0622\u0623"));
+
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
+        onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623"));
+
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
+        onView(withId(R.id.textview)).check(hasSelection("abc \u0621\u0622\u0623 def"));
+    }
+
+    @SmallTest
     public void testSelectionHandles_multiLine() throws Exception {
         final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n" + "opqr";
         onView(withId(R.id.textview)).perform(click());
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
index 1dd6e17..4cecb65 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
@@ -17,6 +17,10 @@
 package android.widget.espresso;
 
 import static android.support.test.espresso.action.ViewActions.actionWithAssertions;
+
+import org.hamcrest.core.Is;
+import org.hamcrest.core.IsInstanceOf;
+
 import android.graphics.Rect;
 import android.support.test.espresso.PerformException;
 import android.support.test.espresso.ViewAction;
@@ -29,6 +33,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.Editor;
+import android.widget.Editor.HandleView;
 import android.widget.TextView;
 
 /**
@@ -311,18 +316,87 @@
      * @param endIndex The index of the TextView's text to end the drag at
      */
     public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex) {
-        final int currentOffset = handleType == Handle.SELECTION_START ?
-                textView.getSelectionStart() : textView.getSelectionEnd();
+        return dragHandle(textView, handleType, endIndex, true);
+    }
+
+    /**
+     * Returns an action that tap then drags on the handle from the current position to endIndex on
+     * the TextView.<br>
+     * <br>
+     * View constraints:
+     * <ul>
+     * <li>must be a TextView's drag-handle displayed on screen
+     * <ul>
+     *
+     * @param textView TextView the handle is on
+     * @param handleType Type of the handle
+     * @param endIndex The index of the TextView's text to end the drag at
+     * @param primary whether to use primary direction to get coordinate form index when endIndex is
+     * at a direction boundary.
+     */
+    public static ViewAction dragHandle(TextView textView, Handle handleType, int endIndex,
+            boolean primary) {
         return actionWithAssertions(
                 new DragAction(
                         DragAction.Drag.TAP,
-                        new HandleCoordinates(textView, handleType, currentOffset),
-                        new HandleCoordinates(textView, handleType, endIndex),
+                        new CurrentHandleCoordinates(textView),
+                        new HandleCoordinates(textView, handleType, endIndex, primary),
                         Press.FINGER,
                         Editor.HandleView.class));
     }
 
     /**
+     * A provider of the x, y coordinates of the handle dragging point.
+     */
+    private static final class CurrentHandleCoordinates implements CoordinatesProvider {
+        // Must be larger than Editor#LINE_SLOP_MULTIPLIER_FOR_HANDLEVIEWS.
+        private final TextView mTextView;
+        private final String mActionDescription;
+
+
+        public CurrentHandleCoordinates(TextView textView) {
+            mTextView = textView;
+            mActionDescription = "Could not locate handle.";
+        }
+
+        @Override
+        public float[] calculateCoordinates(View view) {
+            try {
+                return locateHandle(view);
+            } catch (StringIndexOutOfBoundsException e) {
+                throw new PerformException.Builder()
+                        .withActionDescription(mActionDescription)
+                        .withViewDescription(HumanReadables.describe(view))
+                        .withCause(e)
+                        .build();
+            }
+        }
+
+        private float[] locateHandle(View view) {
+            final Rect bounds = new Rect();
+            view.getBoundsOnScreen(bounds);
+            final Rect visibleDisplayBounds = new Rect();
+            mTextView.getWindowVisibleDisplayFrame(visibleDisplayBounds);
+            visibleDisplayBounds.right -= 1;
+            visibleDisplayBounds.bottom -= 1;
+            if (!visibleDisplayBounds.intersect(bounds)) {
+                throw new PerformException.Builder()
+                        .withActionDescription(mActionDescription
+                                + " The handle is entirely out of the visible display frame of"
+                                + "the TextView's window.")
+                        .withViewDescription(HumanReadables.describe(view))
+                        .build();
+            }
+            final float dragPointX = Math.max(Math.min(bounds.centerX(),
+                    visibleDisplayBounds.right), visibleDisplayBounds.left);
+            final float verticalOffset = bounds.height() * 0.7f;
+            final float dragPointY = Math.max(Math.min(bounds.top + verticalOffset,
+                    visibleDisplayBounds.bottom), visibleDisplayBounds.top);
+            return new float[] {dragPointX, dragPointY};
+        }
+    }
+
+    /**
      * A provider of the x, y coordinates of the handle that points the specified text index in a
      * text view.
      */
@@ -332,14 +406,17 @@
         private final TextView mTextView;
         private final Handle mHandleType;
         private final int mIndex;
+        private final boolean mPrimary;
         private final String mActionDescription;
 
-        public HandleCoordinates(TextView textView, Handle handleType, int index) {
+        public HandleCoordinates(TextView textView, Handle handleType, int index, boolean primary) {
             mTextView = textView;
             mHandleType = handleType;
             mIndex = index;
+            mPrimary = primary;
             mActionDescription = "Could not locate " + handleType.toString()
-                    + " handle that points text index: " + index;
+                    + " handle that points text index: " + index
+                    + " (" + (primary ? "primary" : "secondary" ) + ")";
         }
 
         @Override
@@ -356,17 +433,26 @@
         }
 
         private float[] locateHandlePointsTextIndex(View view) {
+            if (!(view instanceof HandleView)) {
+                throw new PerformException.Builder()
+                        .withActionDescription(mActionDescription + " The view is not a HandleView")
+                        .withViewDescription(HumanReadables.describe(view))
+                        .build();
+            }
+            final HandleView handleView = (HandleView) view;
             final int currentOffset = mHandleType == Handle.SELECTION_START ?
                     mTextView.getSelectionStart() : mTextView.getSelectionEnd();
 
             final Layout layout = mTextView.getLayout();
+
             final int currentLine = layout.getLineForOffset(currentOffset);
             final int targetLine = layout.getLineForOffset(mIndex);
-
+            final float currentX = handleView.getHorizontal(layout, currentOffset);
+            final float currentY = layout.getLineTop(currentLine);
             final float[] currentCoordinates =
-                    (new TextCoordinates(currentOffset)).calculateCoordinates(mTextView);
+                    TextCoordinates.convertToScreenCoordinates(mTextView, currentX, currentY);
             final float[] targetCoordinates =
-                    (new TextCoordinates(mIndex)).calculateCoordinates(mTextView);
+                    (new TextCoordinates(mIndex, mPrimary)).calculateCoordinates(mTextView);
             final Rect bounds = new Rect();
             view.getBoundsOnScreen(bounds);
             final Rect visibleDisplayBounds = new Rect();
@@ -403,17 +489,24 @@
     private static final class TextCoordinates implements CoordinatesProvider {
 
         private final int mIndex;
+        private final boolean mPrimary;
         private final String mActionDescription;
 
         public TextCoordinates(int index) {
+            this(index, true);
+        }
+
+        public TextCoordinates(int index, boolean primary) {
             mIndex = index;
-            mActionDescription = "Could not locate text at index: " + mIndex;
+            mPrimary = primary;
+            mActionDescription = "Could not locate text at index: " + mIndex
+                    + " (" + (primary ? "primary" : "secondary" ) + ")";
         }
 
         @Override
         public float[] calculateCoordinates(View view) {
             try {
-                return locateTextAtIndex((TextView) view, mIndex);
+                return locateTextAtIndex((TextView) view, mIndex, mPrimary);
             } catch (ClassCastException e) {
                 throw new PerformException.Builder()
                         .withActionDescription(mActionDescription)
@@ -432,19 +525,30 @@
         /**
          * @throws StringIndexOutOfBoundsException
          */
-        private float[] locateTextAtIndex(TextView textView, int index) {
+        private float[] locateTextAtIndex(TextView textView, int index, boolean primary) {
             if (index < 0 || index > textView.getText().length()) {
                 throw new StringIndexOutOfBoundsException(index);
             }
-            final int[] xy = new int[2];
-            textView.getLocationOnScreen(xy);
             final Layout layout = textView.getLayout();
             final int line = layout.getLineForOffset(index);
-            final float x = textView.getTotalPaddingLeft() - textView.getScrollX()
-                    + layout.getPrimaryHorizontal(index);
-            final float y = textView.getTotalPaddingTop() - textView.getScrollY()
-                    + layout.getLineTop(line);
-            return new float[]{x + xy[0], y + xy[1]};
+            return convertToScreenCoordinates(textView,
+                    (primary ? layout.getPrimaryHorizontal(index)
+                            : layout.getSecondaryHorizontal(index)),
+                    layout.getLineTop(line));
+        }
+
+        /**
+         * Convert TextView's local coordinates to on screen coordinates.
+         * @param textView the TextView
+         * @param x local horizontal coordinate
+         * @param y local vertical coordinate
+         * @return
+         */
+        public static float[] convertToScreenCoordinates(TextView textView, float x, float y) {
+            final int[] xy = new int[2];
+            textView.getLocationOnScreen(xy);
+            return new float[]{ x + textView.getTotalPaddingLeft() - textView.getScrollX() + xy[0],
+                    y + textView.getTotalPaddingTop() - textView.getScrollY() + xy[1] };
         }
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
index 1966313..7519627 100644
--- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
@@ -291,9 +291,6 @@
 
         @Override
         public void onActionModeFinished(ActionMode mode) {}
-
-        @Override
-        public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, Menu menu) {}
     }
 
     private static final class MockActionModeCallback implements ActionMode.Callback {
diff --git a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java
new file mode 100644
index 0000000..fbf5523
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import junit.framework.TestCase;
+
+public class ProgressReporterTest extends TestCase {
+    private ProgressReporter r;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        r = new ProgressReporter(0, null);
+    }
+
+    private void assertProgress(int expected) {
+        assertEquals(expected, r.getProgress());
+    }
+
+    private void assertRange(int start, int len) {
+        final int[] range = r.getSegmentRange();
+        assertEquals("start", start, range[0]);
+        assertEquals("len", len, range[1]);
+    }
+
+    public void testBasic() throws Exception {
+        assertProgress(0);
+
+        r.setProgress(20);
+        assertProgress(20);
+
+        r.setProgress(-20);
+        assertProgress(0);
+
+        r.setProgress(1024);
+        assertProgress(100);
+    }
+
+    public void testSegment() throws Exception {
+        r.setProgress(20);
+        assertProgress(20);
+
+        final int[] lastRange = r.startSegment(40);
+        {
+            assertProgress(20);
+
+            r.setProgress(50);
+            assertProgress(40);
+        }
+        r.endSegment(lastRange);
+        assertProgress(60);
+
+        r.setProgress(80);
+        assertProgress(80);
+    }
+
+    public void testSegmentOvershoot() throws Exception {
+        r.setProgress(20);
+        assertProgress(20);
+
+        final int[] lastRange = r.startSegment(40);
+        {
+            r.setProgress(-100, 2);
+            assertProgress(20);
+
+            r.setProgress(1, 2);
+            assertProgress(40);
+
+            r.setProgress(100, 2);
+            assertProgress(60);
+        }
+        r.endSegment(lastRange);
+        assertProgress(60);
+    }
+
+    public void testSegmentNested() throws Exception {
+        r.setProgress(20);
+        assertProgress(20);
+        assertRange(0, 100);
+
+        final int[] lastRange = r.startSegment(40);
+        assertRange(20, 40);
+        {
+            r.setProgress(50);
+            assertProgress(40);
+
+            final int[] lastRange2 = r.startSegment(25);
+            assertRange(40, 10);
+            {
+                r.setProgress(0);
+                assertProgress(40);
+
+                r.setProgress(50);
+                assertProgress(45);
+
+                r.setProgress(100);
+                assertProgress(50);
+            }
+            r.endSegment(lastRange2);
+            assertProgress(50);
+        }
+        r.endSegment(lastRange);
+        assertProgress(60);
+    }
+}
diff --git a/docs/html/guide/topics/data/data-storage.jd b/docs/html/guide/topics/data/data-storage.jd
index 46db371..a745d00 100644
--- a/docs/html/guide/topics/data/data-storage.jd
+++ b/docs/html/guide/topics/data/data-storage.jd
@@ -178,6 +178,20 @@
 android.content.Context#MODE_WORLD_READABLE}, and {@link
 android.content.Context#MODE_WORLD_WRITEABLE}.</p>
 
+<p class="note"><strong>Note:</strong> The constants {@link
+android.content.Context#MODE_WORLD_READABLE} and {@link
+android.content.Context#MODE_WORLD_WRITEABLE} have been deprecated since API level 17.
+Starting from Android N their use will result in a {@link java.lang.SecurityException}
+to be thrown.
+This means that apps targeting Android N and higher
+cannot share private files by name, and attempts to share a "file://" URI will result in a
+{@link android.os.FileUriExposedException} to be thrown. If your app needs to share private
+files with other apps, it may use a {@link android.support.v4.content.FileProvider} with
+the {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}.
+See also <a
+href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files</a>.
+</p>
+
 <p>To read a file from internal storage:</p>
 
 <ol>
diff --git a/docs/html/training/basics/data-storage/files.jd b/docs/html/training/basics/data-storage/files.jd
index 49a9169..58a1d5f 100644
--- a/docs/html/training/basics/data-storage/files.jd
+++ b/docs/html/training/basics/data-storage/files.jd
@@ -59,7 +59,7 @@
 <p><b>Internal storage:</b></p>
 <ul>
 <li>It's always available.</li>
-<li>Files saved here are accessible by only your app by default.</li>
+<li>Files saved here are accessible by only your app.</li>
 <li>When the user uninstalls your app, the system removes all your app's files from
 internal storage.</li>
 </ul>
@@ -83,6 +83,12 @@
 with other apps or allow the user to access with a computer.</p>
 </div>
 
+<p class="note">
+<strong>Note:</strong> Before Android N, internal files could be made accessible to other
+apps by means of relaxing file system permissions. This is no longer the case. If you wish
+to make the content of a private file accessible to other apps, your app may use the
+{@link android.support.v4.content.FileProvider}. See <a
+href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files</a>.</p>
 
 <p class="note" style="clear:both">
 <strong>Tip:</strong> Although apps are installed onto the internal storage by
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 5efc00c..b6a209f 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -45,15 +45,11 @@
                 int outlineLeft, int outlineTop, int outlineRight, int outlineBottom,
                 float outlineRadius, int outlineAlpha, float decodeScale) {
             opticalRect = new Rect(opticalLeft, opticalTop, opticalRight, opticalBottom);
-            outlineRect = new Rect(outlineLeft, outlineTop, outlineRight, outlineBottom);
+            opticalRect.scale(decodeScale);
 
-            if (decodeScale != 1.0f) {
-                // if bitmap was scaled when decoded, scale the insets from the metadata values
-                opticalRect.scale(decodeScale);
+            outlineRect = scaleInsets(outlineLeft, outlineTop,
+                    outlineRight, outlineBottom, decodeScale);
 
-                // round inward while scaling outline, as the outline should always be conservative
-                outlineRect.scaleRoundIn(decodeScale);
-            }
             this.outlineRadius = outlineRadius * decodeScale;
             this.outlineAlpha = outlineAlpha / 255.0f;
         }
@@ -62,6 +58,23 @@
         public final Rect outlineRect;
         public final float outlineRadius;
         public final float outlineAlpha;
+
+        /**
+         * Scales up the rect by the given scale, ceiling values, so actual outline Rect
+         * grows toward the inside.
+         */
+        public static Rect scaleInsets(int left, int top, int right, int bottom, float scale) {
+            if (scale == 1.0f) {
+                return new Rect(left, top, right, bottom);
+            }
+
+            Rect result = new Rect();
+            result.left = (int) Math.ceil(left * scale);
+            result.top = (int) Math.ceil(top * scale);
+            result.right = (int) Math.ceil(right * scale);
+            result.bottom = (int) Math.ceil(bottom * scale);
+            return  result;
+        }
     }
 
     private final Bitmap mBitmap;
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index da3deff..de391af 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -16,6 +16,9 @@
 
 package android.graphics;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 /**
  * The Path class encapsulates compound (multiple contour) geometric paths
  * consisting of straight line segments, quadratic curves, and cubic curves.
@@ -91,10 +94,22 @@
 
     /** Replace the contents of this with the contents of src.
     */
-    public void set(Path src) {
-        if (this != src) {
-            isSimplePath = src.isSimplePath;
-            native_set(mNativePath, src.mNativePath);
+    public void set(@NonNull Path src) {
+        if (this == src) {
+            return;
+        }
+        isSimplePath = src.isSimplePath;
+        native_set(mNativePath, src.mNativePath);
+        if (!isSimplePath) {
+            return;
+        }
+
+        if (rects != null && src.rects != null) {
+            rects.set(src.rects);
+        } else if (rects != null && src.rects == null) {
+            rects.setEmpty();
+        } else if (src.rects != null) {
+            rects = new Region(src.rects);
         }
     }
 
@@ -685,13 +700,13 @@
      * @param dst The translated path is written here. If this is null, then
      *            the original path is modified.
      */
-    public void offset(float dx, float dy, Path dst) {
-        long dstNative = 0;
+    public void offset(float dx, float dy, @Nullable Path dst) {
         if (dst != null) {
-            dstNative = dst.mNativePath;
-            dst.isSimplePath = false;
+            dst.set(this);
+        } else {
+            dst = this;
         }
-        native_offset(mNativePath, dx, dy, dstNative);
+        dst.offset(dx, dy);
     }
 
     /**
@@ -701,7 +716,15 @@
      * @param dy The amount in the Y direction to offset the entire path
      */
     public void offset(float dx, float dy) {
-        isSimplePath = false;
+        if (isSimplePath && rects == null) {
+            // nothing to offset
+            return;
+        }
+        if (isSimplePath && dx == Math.rint(dx) && dy == Math.rint(dy)) {
+            rects.translate((int) dx, (int) dy);
+        } else {
+            isSimplePath = false;
+        }
         native_offset(mNativePath, dx, dy);
     }
 
@@ -823,7 +846,6 @@
     private static native void native_addPath(long nPath, long src, float dx, float dy);
     private static native void native_addPath(long nPath, long src);
     private static native void native_addPath(long nPath, long src, long matrix);
-    private static native void native_offset(long nPath, float dx, float dy, long dst_path);
     private static native void native_offset(long nPath, float dx, float dy);
     private static native void native_setLastPoint(long nPath, float dx, float dy);
     private static native void native_transform(long nPath, long matrix, long dst_path);
diff --git a/graphics/java/android/graphics/PathMeasure.java b/graphics/java/android/graphics/PathMeasure.java
index 0416159..2848949 100644
--- a/graphics/java/android/graphics/PathMeasure.java
+++ b/graphics/java/android/graphics/PathMeasure.java
@@ -112,7 +112,7 @@
      * Given a start and stop distance, return in dst the intervening
      * segment(s). If the segment is zero-length, return false, else return
      * true. startD and stopD are pinned to legal values (0..getLength()).
-     * If startD <= stopD then return false (and leave dst untouched).
+     * If startD >= stopD then return false (and leave dst untouched).
      * Begin the segment with a moveTo if startWithMoveTo is true.
      *
      * <p>On {@link android.os.Build.VERSION_CODES#KITKAT} and earlier
@@ -121,6 +121,19 @@
      * such as <code>dst.rLineTo(0, 0)</code>.</p>
      */
     public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) {
+        // Skia used to enforce this as part of it's API, but has since relaxed that restriction
+        // so to maintain consistency in our API we enforce the preconditions here.
+        float length = getLength();
+        if (startD < 0) {
+            startD = 0;
+        }
+        if (stopD > length) {
+            stopD = length;
+        }
+        if (startD >= stopD) {
+            return false;
+        }
+
         dst.isSimplePath = false;
         return native_getSegment(native_instance, startD, stopD, dst.ni(), startWithMoveTo);
     }
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 93ef3f0..7f579a2 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -647,16 +647,4 @@
         }
     }
 
-    /**
-     * Scales up the rect by the given scale, rounding values toward the inside.
-     * @hide
-     */
-    public void scaleRoundIn(float scale) {
-        if (scale != 1.0f) {
-            left = (int) Math.ceil(left * scale);
-            top = (int) Math.ceil(top * scale);
-            right = (int) Math.floor(right * scale);
-            bottom = (int) Math.floor(bottom * scale);
-        }
-    }
 }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 3915984..4f600b4 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -1198,6 +1198,8 @@
 
     /**
      * Inflate this Drawable from an XML resource optionally styled by a theme.
+     * This can't be called more than once for each Drawable. Note that framework may have called
+     * this once to create the Drawable instance from XML resource.
      *
      * @param r Resources used to resolve attribute values
      * @param parser XML parser from which to inflate this Drawable
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 51221b4..2b950d3 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -243,13 +243,15 @@
     }
 
     /**
-     * Invokes {@link #loadDrawable(Context)} on a background thread
-     * and then runs <code>andThen</code> on the UI thread when finished.
+     * Invokes {@link #loadDrawable(Context)} on a background thread and notifies the <code>
+     * {@link OnDrawableLoadedListener#onDrawableLoaded listener} </code> on the {@code handler}
+     * when finished.
      *
      * @param context {@link Context Context} in which to load the drawable; see
      *                {@link #loadDrawable(Context)}
-     * @param listener a callback to run on the provided
-     * @param handler {@link Handler} on which to run <code>andThen</code>.
+     * @param listener to be {@link OnDrawableLoadedListener#onDrawableLoaded notified} when
+     *                 {@link #loadDrawable(Context)} finished
+     * @param handler {@link Handler} on which to notify the {@code listener}
      */
     public void loadDrawableAsync(Context context, final OnDrawableLoadedListener listener,
             Handler handler) {
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 5b1cc80..d962385 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -706,18 +706,9 @@
 
         final NinePatch.InsetStruct insets = ninePatch.getBitmap().getNinePatchInsets();
         if (insets != null) {
-            if (mOutlineInsets == null) {
-                mOutlineInsets = new Rect();
-            }
-            final Rect outlineInsets = insets.outlineRect;
-            mOutlineInsets.left = Drawable.scaleFromDensity(
-                    outlineInsets.left, sourceDensity, targetDensity, false);
-            mOutlineInsets.top = Drawable.scaleFromDensity(
-                    outlineInsets.top, sourceDensity, targetDensity, false);
-            mOutlineInsets.right = Drawable.scaleFromDensity(
-                    outlineInsets.right, sourceDensity, targetDensity, false);
-            mOutlineInsets.bottom = Drawable.scaleFromDensity(
-                    outlineInsets.bottom, sourceDensity, targetDensity, false);
+            Rect outlineRect = insets.outlineRect;
+            mOutlineInsets = NinePatch.InsetStruct.scaleInsets(outlineRect.left, outlineRect.top,
+                    outlineRect.right, outlineRect.bottom, targetDensity / (float) sourceDensity);
             mOutlineRadius = Drawable.scaleFromDensity(
                     insets.outlineRadius, sourceDensity, targetDensity);
         } else {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
index 156f45f6..be390ff 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
@@ -193,12 +193,12 @@
         putSignatureImpl("NONEwithECDSA",
                 PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$NONE");
 
-        putSignatureImpl("ECDSA", PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA1");
-        put("Alg.Alias.Signature.SHA1withECDSA", "ECDSA");
-        put("Alg.Alias.Signature.ECDSAwithSHA1", "ECDSA");
+        putSignatureImpl("SHA1withECDSA", PACKAGE_NAME + ".AndroidKeyStoreECDSASignatureSpi$SHA1");
+        put("Alg.Alias.Signature.ECDSA", "SHA1withECDSA");
+        put("Alg.Alias.Signature.ECDSAwithSHA1", "SHA1withECDSA");
         // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA1(1)
-        put("Alg.Alias.Signature.1.2.840.10045.4.1", "ECDSA");
-        put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10045.2.1", "ECDSA");
+        put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
+        put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10045.2.1", "SHA1withECDSA");
 
         // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA2(3)
         putSignatureImpl("SHA224withECDSA",
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 516591b..01f9cde 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -266,7 +266,8 @@
         tests/unit/FrameBuilderTests.cpp \
         tests/unit/LeakCheckTests.cpp \
         tests/unit/OpDumperTests.cpp \
-        tests/unit/RecordingCanvasTests.cpp
+        tests/unit/RecordingCanvasTests.cpp \
+        tests/unit/SkiaCanvasTests.cpp
 endif
 
 include $(LOCAL_PATH)/hwui_static_deps.mk
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 06b712e..ea4f4eb 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -506,6 +506,22 @@
     renderer.renderGlop(state, glop);
 }
 
+void BakedOpDispatcher::onColorOp(BakedOpRenderer& renderer, const ColorOp& op, const BakedOpState& state) {
+    SkPaint paint;
+    paint.setColor(op.color);
+    paint.setXfermodeMode(op.mode);
+
+    Glop glop;
+    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+            .setRoundRectClipState(state.roundRectClipState)
+            .setMeshUnitQuad()
+            .setFillPaint(paint, state.alpha)
+            .setTransform(Matrix4::identity(), TransformFlags::None)
+            .setModelViewMapUnitToRect(state.computedState.clipState->rect)
+            .build();
+    renderer.renderGlop(state, glop);
+}
+
 void BakedOpDispatcher::onFunctorOp(BakedOpRenderer& renderer, const FunctorOp& op, const BakedOpState& state) {
     renderer.renderFunctor(op, state);
 }
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index fae8e48..0ebb886 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -572,6 +572,12 @@
     deferOvalOp(*resolvedOp);
 }
 
+void FrameBuilder::deferColorOp(const ColorOp& op) {
+    BakedOpState* bakedState = tryBakeUnboundedOpState(op);
+    if (!bakedState) return; // quick rejected
+    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
+}
+
 void FrameBuilder::deferFunctorOp(const FunctorOp& op) {
     BakedOpState* bakedState = tryBakeUnboundedOpState(op);
     if (!bakedState) return; // quick rejected
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index c305f65..2246cf9c 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -21,6 +21,8 @@
 #include <cstdio>
 #include <errno.h>
 #include <inttypes.h>
+#include <limits>
+#include <cmath>
 #include <sys/mman.h>
 
 namespace android {
@@ -202,6 +204,40 @@
 
 }
 
+static bool shouldReplace(SlowFrame& existing, SlowFrame& candidate) {
+    if (candidate.whenHours - existing.whenHours >= 24) {
+        // If the old slowframe is over 24 hours older than the candidate,
+        // replace it. It's too stale
+        return true;
+    }
+    if (candidate.frametimeMs > existing.frametimeMs) {
+        return true;
+    }
+    return false;
+}
+
+void JankTracker::updateSlowest(const FrameInfo& frame) {
+    uint16_t durationMs = static_cast<uint16_t>(std::min(
+            ns2ms(frame[FrameInfoIndex::FrameCompleted] - frame[FrameInfoIndex::IntendedVsync]),
+            static_cast<nsecs_t>(std::numeric_limits<uint16_t>::max())));
+    uint16_t startHours = static_cast<uint16_t>(std::lround(
+            ns2s(frame[FrameInfoIndex::IntendedVsync]) / 3600.0f));
+    SlowFrame* toReplace = nullptr;
+    SlowFrame thisFrame{startHours, durationMs};
+    // First find the best candidate for replacement
+    for (SlowFrame& existing : mData->slowestFrames) {
+        // If we should replace the current data with the replacement candidate,
+        // it means the current data is worse than the replacement candidate
+        if (!toReplace || shouldReplace(existing, *toReplace)) {
+            toReplace = &existing;
+        }
+    }
+    // Now see if we should replace it
+    if (shouldReplace(*toReplace, thisFrame)) {
+        *toReplace = thisFrame;
+    }
+}
+
 void JankTracker::addFrame(const FrameInfo& frame) {
     mData->totalFrameCount++;
     // Fast-path for jank-free frames
@@ -215,6 +251,11 @@
         return;
     }
 
+    // For slowest frames we are still interested in frames that are otherwise
+    // exempt (such as first-draw). Although those frames don't directly impact
+    // smoothness, they do impact responsiveness.
+    updateSlowest(frame);
+
     if (frame[FrameInfoIndex::Flags] & EXEMPT_FRAMES_FLAGS) {
         return;
     }
@@ -247,6 +288,11 @@
     dprintf(fd, "\n90th percentile: %ums", findPercentile(data, 90));
     dprintf(fd, "\n95th percentile: %ums", findPercentile(data, 95));
     dprintf(fd, "\n99th percentile: %ums", findPercentile(data, 99));
+    dprintf(fd, "\nSlowest frames over last 24h: ");
+    for (auto& slowFrame : data->slowestFrames) {
+        if (!slowFrame.frametimeMs) continue;
+        dprintf(fd, "%ums ", slowFrame.frametimeMs);
+    }
     for (int i = 0; i < NUM_BUCKETS; i++) {
         dprintf(fd, "\nNumber %s: %u", JANK_TYPE_NAMES[i], data->jankTypeCounts[i]);
     }
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 3887e5e..1a4a489 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -39,6 +39,11 @@
     NUM_BUCKETS,
 };
 
+struct SlowFrame {
+    uint16_t whenHours; // When this occurred in CLOCK_MONOTONIC in hours
+    uint16_t frametimeMs; // How long the frame took in ms
+};
+
 // Try to keep as small as possible, should match ASHMEM_SIZE in
 // GraphicsStatsService.java
 struct ProfileData {
@@ -49,6 +54,8 @@
     uint32_t totalFrameCount;
     uint32_t jankFrameCount;
     nsecs_t statStartTime;
+
+    std::array<SlowFrame, 10> slowestFrames;
 };
 
 // TODO: Replace DrawProfiler with this
@@ -71,6 +78,7 @@
 private:
     void freeData();
     void setFrameInterval(nsecs_t frameIntervalNanos);
+    void updateSlowest(const FrameInfo& frame);
 
     static uint32_t findPercentile(const ProfileData* data, int p);
     static void dumpData(const ProfileData* data, int fd);
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index 96a57b6..64c604a 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -90,6 +90,7 @@
         UNMERGEABLE_OP_FN(ArcOp) \
         UNMERGEABLE_OP_FN(BitmapMeshOp) \
         UNMERGEABLE_OP_FN(BitmapRectOp) \
+        UNMERGEABLE_OP_FN(ColorOp) \
         UNMERGEABLE_OP_FN(FunctorOp) \
         UNMERGEABLE_OP_FN(LinesOp) \
         UNMERGEABLE_OP_FN(OvalOp) \
@@ -256,6 +257,16 @@
     const float* radius;
 };
 
+struct ColorOp : RecordedOp {
+    // Note: unbounded op that will fillclip, so no bounds/matrix needed
+    ColorOp(const ClipBase* localClip, int color, SkXfermode::Mode mode)
+            : RecordedOp(RecordedOpId::ColorOp, Rect(), Matrix4::identity(), localClip, nullptr)
+            , color(color)
+            , mode(mode) {}
+    const int color;
+    const SkXfermode::Mode mode;
+};
+
 struct FunctorOp : RecordedOp {
     // Note: undefined record-time bounds, since this op fills the clip
     // TODO: explicitly define bounds
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 4eeadb7..f43dade 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -234,10 +234,10 @@
 // android/graphics/Canvas draw operations
 // ----------------------------------------------------------------------------
 void RecordingCanvas::drawColor(int color, SkXfermode::Mode mode) {
-    SkPaint paint;
-    paint.setColor(color);
-    paint.setXfermodeMode(mode);
-    drawPaint(paint);
+    addOp(alloc().create_trivial<ColorOp>(
+            getRecordedClip(),
+            color,
+            mode));
 }
 
 void RecordingCanvas::drawPaint(const SkPaint& paint) {
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 1eb4fa0..acb88e2 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -191,13 +191,16 @@
             const SkPaint* paint) override;
 
     // Text
-    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount,
-            const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
-            float boundsRight, float boundsBottom, float totalAdvance) override;
-    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path,
-            float hOffset, float vOffset, const SkPaint& paint) override;
     virtual bool drawTextAbsolutePos() const override { return false; }
 
+protected:
+    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
+            const SkPaint& paint, float x, float y,
+            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+            float totalAdvance) override;
+    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
+            float hOffset, float vOffset, const SkPaint& paint) override;
+
 private:
     const ClipBase* getRecordedClip() {
         return mState.writableSnapshot()->mutateClipArea().serializeClip(alloc());
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index b1ecb71..5d24fa0 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -147,13 +147,6 @@
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) override;
 
-    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
-            float totalAdvance) override;
-    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
-            float hOffset, float vOffset, const SkPaint& paint) override;
-
     virtual bool drawTextAbsolutePos() const  override { return true; }
     virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
 
@@ -169,6 +162,14 @@
     virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
     virtual void callDrawGLFunction(Functor* functor) override;
 
+protected:
+    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
+            const SkPaint& paint, float x, float y,
+            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+            float totalAdvance) override;
+    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
+            float hOffset, float vOffset, const SkPaint& paint) override;
+
 private:
     struct SaveRec {
         int              saveCount;
@@ -761,14 +762,8 @@
         const SkPaint& paint, float x, float y,
         float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
         float totalAdvance) {
-    // Set align to left for drawing, as we don't want individual
-    // glyphs centered or right-aligned; the offset above takes
-    // care of all alignment.
-    SkPaint paintCopy(paint);
-    paintCopy.setTextAlign(SkPaint::kLeft_Align);
-
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    mCanvas->drawPosText(text, count << 1, reinterpret_cast<const SkPoint*>(positions), paintCopy);
+    mCanvas->drawPosText(text, count << 1, reinterpret_cast<const SkPoint*>(positions), paint);
     drawTextDecorations(x, y, totalAdvance, paint);
 }
 
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index c612480..9df32b28 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -318,12 +318,17 @@
         posArray = pointStorage.get();
     }
 
-    // compute conservative bounds
-    // NOTE: We could call the faster paint.getFontBounds for a less accurate,
-    //       but even more conservative bounds if this  is too slow.
+    // Compute conservative bounds.  If the content has already been processed
+    // by Minikin then it had already computed these bounds.  Unfortunately,
+    // there is no way to capture those bounds as part of the Skia drawPosText
+    // API so we need to do that computation again here.
     SkRect bounds;
-    glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
-    bounds.offset(x, y);
+    for (int i = 0; i < glyphs.count; i++) {
+        SkRect glyphBounds;
+        glyphs.paint.measureText(&glyphs.glyphIDs[i], sizeof(uint16_t), &glyphBounds);
+        glyphBounds.offset(pos[i].fX, pos[i].fY);
+        bounds.join(glyphBounds);
+    }
 
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
     mCanvas->drawGlyphs(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index 8c3eea3..7bfa15a 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -166,6 +166,11 @@
         bounds.offset(x, y);
     }
 
+    // Set align to left for drawing, as we don't want individual
+    // glyphs centered or right-aligned; the offset above takes
+    // care of all alignment.
+    paint.setTextAlign(Paint::kLeft_Align);
+
     DrawTextFunctor f(layout, this, glyphs.get(), pos.get(),
             paint, x, y, bounds, layout.getAdvance());
     MinikinUtils::forFontRun(layout, &paint, f);
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index dc669f0..5dbda43 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -53,6 +53,7 @@
 } // namespace SaveFlags
 
 namespace uirenderer {
+class SkiaCanvasProxy;
 namespace VectorDrawable {
 class Tree;
 };
@@ -205,19 +206,6 @@
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) = 0;
 
-    // Text
-    /**
-     * drawText: count is of glyphs
-     * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
-     */
-    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
-            float totalAdvance) = 0;
-    /** drawTextOnPath: count is of glyphs */
-    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
-            float hOffset, float vOffset, const SkPaint& paint) = 0;
-
     /**
      * Specifies if the positions passed to ::drawText are absolute or relative
      * to the (x,y) value provided.
@@ -244,6 +232,22 @@
 
 protected:
     void drawTextDecorations(float x, float y, float length, const SkPaint& paint);
+
+    /**
+     * drawText: count is of glyphs
+     * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
+     */
+    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
+            const SkPaint& paint, float x, float y,
+            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+            float totalAdvance) = 0;
+    /** drawTextOnPath: count is of glyphs */
+    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
+            float hOffset, float vOffset, const SkPaint& paint) = 0;
+
+    friend class DrawTextFunctor;
+    friend class DrawTextOnPathFunctor;
+    friend class uirenderer::SkiaCanvasProxy;
 };
 
 }; // namespace android
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index 69c321c..9599c30 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -30,6 +30,7 @@
 public:
     Paint();
     Paint(const Paint& paint);
+    Paint(const SkPaint& paint);
     ~Paint();
 
     Paint& operator=(const Paint& other);
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index 1172a0e..b27672c 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -29,6 +29,11 @@
         mHyphenEdit(paint.mHyphenEdit) {
 }
 
+Paint::Paint(const SkPaint& paint) : SkPaint(paint),
+        mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
+        mFontVariant(VARIANT_DEFAULT) {
+}
+
 Paint::~Paint() {
 }
 
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index a4aee61..059e9ae 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -16,6 +16,7 @@
 
 #include "TestUtils.h"
 
+#include "hwui/Paint.h"
 #include "DeferredLayerUpdater.h"
 #include "LayerRenderer.h"
 
@@ -41,17 +42,20 @@
 
 sp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater(
         renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
-        std::function<void(Matrix4*)> transformSetupCallback) {
+        const SkMatrix& transform) {
+    Layer* layer = LayerRenderer::createTextureLayer(renderThread.renderState());
+
+    sp<DeferredLayerUpdater> layerUpdater = new DeferredLayerUpdater(layer);
+    layerUpdater->setSize(width, height);
+    layerUpdater->setTransform(&transform);
+
+    // updateLayer so it's ready to draw
     bool isOpaque = true;
     bool forceFilter = true;
     GLenum renderTarget = GL_TEXTURE_EXTERNAL_OES;
-
-    Layer* layer = LayerRenderer::createTextureLayer(renderThread.renderState());
     LayerRenderer::updateTextureLayer(layer, width, height, isOpaque, forceFilter,
-            renderTarget, Matrix4::identity().data);
-    transformSetupCallback(&(layer->getTransform()));
+    renderTarget, Matrix4::identity().data);
 
-    sp<DeferredLayerUpdater> layerUpdater = new DeferredLayerUpdater(layer);
     return layerUpdater;
 }
 
@@ -87,50 +91,17 @@
     *outTotalAdvance = totalAdvance;
 }
 
-void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+
+void TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
         const SkPaint& paint, float x, float y) {
-    // drawing text requires GlyphID TextEncoding (which JNI layer would have done)
-    LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
-            "must use glyph encoding");
-    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
-    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
-
-    std::vector<glyph_t> glyphs;
-    std::vector<float> positions;
-    float totalAdvance;
-    Rect bounds;
-    layoutTextUnscaled(paint, text, &glyphs, &positions, &totalAdvance, &bounds);
-
-    // apply alignment via x parameter (which JNI layer would have done)
-    if (paint.getTextAlign() == SkPaint::kCenter_Align) {
-        x -= totalAdvance / 2;
-    } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
-        x -= totalAdvance;
-    }
-
-    bounds.translate(x, y);
-
-    // Force left alignment, since alignment offset is already baked in
-    SkPaint alignPaintCopy(paint);
-    alignPaintCopy.setTextAlign(SkPaint::kLeft_Align);
-    canvas->drawGlyphs(glyphs.data(), positions.data(), glyphs.size(), alignPaintCopy, x, y,
-                bounds.left, bounds.top, bounds.right, bounds.bottom, totalAdvance);
+    auto utf16 = asciiToUtf16(text);
+    canvas->drawText(utf16.get(), 0, strlen(text), strlen(text), x, y, 0, paint, nullptr);
 }
 
-void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+void TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
         const SkPaint& paint, const SkPath& path) {
-    // drawing text requires GlyphID TextEncoding (which JNI layer would have done)
-    LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
-            "must use glyph encoding");
-    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
-    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
-
-    std::vector<glyph_t> glyphs;
-    while (*text != '\0') {
-        SkUnichar unichar = SkUTF8_NextUnichar(&text);
-        glyphs.push_back(autoCache.getCache()->unicharToGlyph(unichar));
-    }
-    canvas->drawGlyphsOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint);
+    auto utf16 = asciiToUtf16(text);
+    canvas->drawTextOnPath(utf16.get(), strlen(text), 0, path, 0, 0, paint, nullptr);
 }
 
 void TestUtils::TestTask::run() {
@@ -143,12 +114,13 @@
     renderState.onGLContextDestroyed();
 }
 
-std::unique_ptr<uint16_t[]> TestUtils::utf8ToUtf16(const char* str) {
-    const size_t strLen = strlen(str);
-    const ssize_t utf16Len = utf8_to_utf16_length((uint8_t*) str, strLen);
-    std::unique_ptr<uint16_t[]> dst(new uint16_t[utf16Len + 1]);
-    utf8_to_utf16((uint8_t*) str, strLen, (char16_t*) dst.get());
-    return dst;
+std::unique_ptr<uint16_t[]> TestUtils::asciiToUtf16(const char* str) {
+    const int length = strlen(str);
+    std::unique_ptr<uint16_t[]> utf16(new uint16_t[length]);
+    for (int i = 0; i < length; i++) {
+        utf16.get()[i] = str[i];
+    }
+    return utf16;
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index a5e7a5f..2d1e2e9 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -122,7 +122,7 @@
 
     static sp<DeferredLayerUpdater> createTextureLayerUpdater(
             renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
-            std::function<void(Matrix4*)> transformSetupCallback);
+            const SkMatrix& transform);
 
     template<class CanvasType>
     static std::unique_ptr<DisplayList> createDisplayList(int width, int height,
@@ -207,13 +207,13 @@
             std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
             float* outTotalAdvance, Rect* outBounds);
 
-    static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+    static void drawUtf8ToCanvas(Canvas* canvas, const char* text,
             const SkPaint& paint, float x, float y);
 
-    static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+    static void drawUtf8ToCanvas(Canvas* canvas, const char* text,
             const SkPaint& paint, const SkPath& path);
 
-    static std::unique_ptr<uint16_t[]> utf8ToUtf16(const char* str);
+    static std::unique_ptr<uint16_t[]> asciiToUtf16(const char* str);
 
 private:
     static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
index 52039ef..63c067b 100644
--- a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
@@ -42,7 +42,7 @@
     }
 
     void doFrame(int frameNr) override {
-        std::unique_ptr<uint16_t[]> text = TestUtils::utf8ToUtf16(
+        std::unique_ptr<uint16_t[]> text = TestUtils::asciiToUtf16(
                 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
         ssize_t textLength = 26 * 2;
 
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 0aabfb1..dca56d4 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -344,8 +344,9 @@
             EXPECT_TRUE(stroke.contains(fill));
             EXPECT_FALSE(fill.contains(stroke));
 
+            // outset by half the stroke width
             Rect outsetFill(fill);
-            outsetFill.outset(10);
+            outsetFill.outset(5);
             EXPECT_EQ(stroke, outsetFill);
         }
     };
@@ -386,9 +387,7 @@
     };
 
     auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
-            [](Matrix4* transform) {
-        transform->loadTranslate(5, 5, 0);
-    });
+            SkMatrix::MakeTrans(5, 5));
 
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
@@ -428,7 +427,31 @@
     EXPECT_EQ(1, renderer.getIndex()) << "Functor should not be rejected";
 }
 
-RENDERTHREAD_TEST(FrameBuilder, renderNode) {
+RENDERTHREAD_TEST(FrameBuilder, deferColorOp_unbounded) {
+    class ColorTestRenderer : public TestRendererBase {
+    public:
+        void onColorOp(const ColorOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(0, mIndex++);
+            EXPECT_EQ(Rect(200, 200), state.computedState.clippedBounds)
+                    << "Color op should be expanded to bounds of surrounding";
+        }
+    };
+
+    auto unclippedColorView = TestUtils::createNode(0, 0, 10, 10,
+            [](RenderProperties& props, RecordingCanvas& canvas) {
+        props.setClipToBounds(false);
+        canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
+    });
+
+    FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+            TestUtils::createSyncedNodeList(unclippedColorView),
+            sLightGeometry, Caches::getInstance());
+    ColorTestRenderer renderer;
+    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(1, renderer.getIndex()) << "ColorOp should not be rejected";
+}
+
+TEST(FrameBuilder, renderNode) {
     class RenderNodeTestRenderer : public TestRendererBase {
     public:
         void onRectOp(const RectOp& op, const BakedOpState& state) override {
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 6ab5110..1c240db 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -23,6 +23,9 @@
 #include <tests/common/TestUtils.h>
 #include <utils/Color.h>
 
+#include <SkGradientShader.h>
+#include <SkShader.h>
+
 namespace android {
 namespace uirenderer {
 
@@ -223,9 +226,9 @@
 
     ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
     auto op = *(dl->getOps()[0]);
-    EXPECT_EQ(RecordedOpId::RectOp, op.opId);
+    EXPECT_EQ(RecordedOpId::ColorOp, op.opId);
     EXPECT_EQ(nullptr, op.localClip);
-    EXPECT_TRUE(op.unmappedBounds.contains(Rect(200, 200))) << "Expect recording/clip bounds";
+    EXPECT_TRUE(op.unmappedBounds.isEmpty()) << "Expect undefined recorded bounds";
 }
 
 TEST(RecordingCanvas, backgroundAndImage) {
@@ -567,36 +570,69 @@
 
 TEST(RecordingCanvas, refPaint) {
     SkPaint paint;
-    paint.setAntiAlias(true);
-    paint.setTextSize(20);
-    paint.setTextAlign(SkPaint::kLeft_Align);
-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
 
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [&paint](RecordingCanvas& canvas) {
         paint.setColor(SK_ColorBLUE);
-        // first three should use same paint
+        // first two should use same paint
         canvas.drawRect(0, 0, 200, 10, paint);
         SkPaint paintCopy(paint);
         canvas.drawRect(0, 10, 200, 20, paintCopy);
-        TestUtils::drawUtf8ToCanvas(&canvas, "helloworld", paint, 50, 25);
 
         // only here do we use different paint ptr
         paint.setColor(SK_ColorRED);
         canvas.drawRect(0, 20, 200, 30, paint);
     });
     auto ops = dl->getOps();
-    ASSERT_EQ(4u, ops.size());
+    ASSERT_EQ(3u, ops.size());
 
-    // first three are the same
+    // first two are the same
     EXPECT_NE(nullptr, ops[0]->paint);
     EXPECT_NE(&paint, ops[0]->paint);
     EXPECT_EQ(ops[0]->paint, ops[1]->paint);
-    EXPECT_EQ(ops[0]->paint, ops[2]->paint);
 
     // last is different, but still copied / non-null
-    EXPECT_NE(nullptr, ops[3]->paint);
-    EXPECT_NE(ops[0]->paint, ops[3]->paint);
-    EXPECT_NE(&paint, ops[3]->paint);
+    EXPECT_NE(nullptr, ops[2]->paint);
+    EXPECT_NE(ops[0]->paint, ops[2]->paint);
+    EXPECT_NE(&paint, ops[2]->paint);
+}
+
+TEST(RecordingCanvas, refBitmapInShader_bitmapShader) {
+    SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
+    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
+        SkPaint paint;
+        SkAutoTUnref<SkShader> shader(SkShader::CreateBitmapShader(bitmap,
+                SkShader::TileMode::kClamp_TileMode,
+                SkShader::TileMode::kClamp_TileMode));
+        paint.setShader(shader);
+        canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint);
+    });
+    auto& bitmaps = dl->getBitmapResources();
+    EXPECT_EQ(1u, bitmaps.size());
+}
+
+TEST(RecordingCanvas, refBitmapInShader_composeShader) {
+    SkBitmap bitmap = TestUtils::createSkBitmap(100, 100);
+    auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 100, [&bitmap](RecordingCanvas& canvas) {
+        SkPaint paint;
+        SkAutoTUnref<SkShader> shader1(SkShader::CreateBitmapShader(bitmap,
+                SkShader::TileMode::kClamp_TileMode,
+                SkShader::TileMode::kClamp_TileMode));
+
+        SkPoint center;
+        center.set(50, 50);
+        SkColor colors[2];
+        colors[0] = Color::Black;
+        colors[1] = Color::White;
+        SkAutoTUnref<SkShader> shader2(SkGradientShader::CreateRadial(center, 50, colors, nullptr, 2,
+                SkShader::TileMode::kRepeat_TileMode));
+
+        SkAutoTUnref<SkShader> composeShader(SkShader::CreateComposeShader(shader1, shader2,
+                SkXfermode::Mode::kMultiply_Mode));
+        paint.setShader(composeShader);
+        canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint);
+    });
+    auto& bitmaps = dl->getBitmapResources();
+    EXPECT_EQ(1u, bitmaps.size());
 }
 
 TEST(RecordingCanvas, drawText) {
@@ -605,7 +641,7 @@
         paint.setAntiAlias(true);
         paint.setTextSize(20);
         paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-        std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO");
+        std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO");
         canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL);
     });
 
@@ -629,7 +665,7 @@
         paint.setAntiAlias(true);
         paint.setTextSize(20);
         paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-        std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO");
+        std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO");
         canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL);
     });
 
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
new file mode 100644
index 0000000..d6279b4
--- /dev/null
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tests/common/TestUtils.h"
+
+#include <gtest/gtest.h>
+#include <RecordingCanvas.h>
+#include <SkPicture.h>
+#include <SkPictureRecorder.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+/**
+ * Verify that we get the same culling bounds for text for (1) drawing glyphs
+ * directly to a Canvas or (2) going through a SkPicture as an intermediate step.
+ */
+TEST(SkiaCanvasProxy, drawGlyphsViaPicture) {
+    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
+        // setup test variables
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setTextSize(20);
+        static const char* text = "testing text bounds";
+
+        // draw text directly into Recording canvas
+        TestUtils::drawUtf8ToCanvas(&canvas, text, paint, 25, 25);
+
+        // record the same text draw into a SkPicture and replay it into a Recording canvas
+        SkPictureRecorder recorder;
+        SkCanvas* skCanvas = recorder.beginRecording(200, 200, NULL, 0);
+        std::unique_ptr<Canvas> pictCanvas(Canvas::create_canvas(skCanvas));
+        TestUtils::drawUtf8ToCanvas(pictCanvas.get(), text, paint, 25, 25);
+        SkAutoTUnref<const SkPicture> picture(recorder.endRecording());
+
+        canvas.asSkCanvas()->drawPicture(picture);
+    });
+
+    // verify that the text bounds and matrices match
+    ASSERT_EQ(2U, dl->getOps().size());
+    auto directOp = dl->getOps()[0];
+    auto pictureOp = dl->getOps()[1];
+    ASSERT_EQ(RecordedOpId::TextOp, directOp->opId);
+    EXPECT_EQ(directOp->opId, pictureOp->opId);
+    EXPECT_EQ(directOp->unmappedBounds, pictureOp->unmappedBounds);
+    EXPECT_EQ(directOp->localMatrix, pictureOp->localMatrix);
+}
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index a5b3179..4bf0852 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -1888,6 +1888,19 @@
         for (ExifTag tag : IFD_POINTER_TAGS) {
             setAttribute(tag.name, null);
         }
+        // Remove old thumbnail data
+        setAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name, null);
+        setAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name, null);
+
+        // Remove null value tags.
+        for (int hint = 0; hint < EXIF_TAGS.length; ++hint) {
+            for (Object obj : mAttributes[hint].entrySet().toArray()) {
+                Map.Entry entry = (Map.Entry) obj;
+                if (entry.getValue() == null) {
+                    mAttributes[hint].remove(entry.getKey());
+                }
+            }
+        }
 
         // Add IFD pointer tags. The next offset of primary image TIFF IFD will have thumbnail IFD
         // offset when there is one or more tags in the thumbnail IFD.
@@ -1900,25 +1913,12 @@
         if (!mAttributes[IFD_GPS_HINT].isEmpty()) {
             mAttributes[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[1].name, "0");
         }
-        // Remove old thumbnail data
-        setAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name, null);
-        setAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name, null);
         if (mHasThumbnail) {
             mAttributes[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_TAG.name, "0");
             mAttributes[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name,
                     String.valueOf(mThumbnailLength));
         }
 
-        // Remove null value tags.
-        for (int hint = 0; hint < EXIF_TAGS.length; ++hint) {
-            for (Object obj : mAttributes[hint].entrySet().toArray()) {
-                Map.Entry entry = (Map.Entry) obj;
-                if (entry.getValue() == null) {
-                    mAttributes[hint].remove(entry.getKey());
-                }
-            }
-        }
-
         // Calculate IFD group data area sizes. IFD group data area is assigned to save the entry
         // value which has a bigger size than 4 bytes.
         for (int i = 0; i < 5; ++i) {
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index fe2796c..c1805cb 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -57,8 +57,9 @@
  * <h3>Standard Extra Data</h3>
  *
  * <p>These are the current standard fields that can be used as extra data via
- * {@link #subscribe(String, Bundle, SubscriptionCallback)}, {@link #unsubscribe(String, Bundle)},
- * and {@link SubscriptionCallback#onChildrenLoaded(String, List, Bundle)}.
+ * {@link #subscribe(String, Bundle, SubscriptionCallback)},
+ * {@link #unsubscribe(String, SubscriptionCallback)}, and
+ * {@link SubscriptionCallback#onChildrenLoaded(String, List, Bundle)}.
  *
  * <ul>
  *     <li> {@link #EXTRA_PAGE}
@@ -383,7 +384,7 @@
     }
 
     /**
-     * Unsubscribes for changes to the children of the specified media id.
+     * Unsubscribes for changes to the children of the specified media id through a callback.
      * <p>
      * The query callback will no longer be invoked for results associated with
      * this id once this method returns.
@@ -391,13 +392,13 @@
      *
      * @param parentId The id of the parent media item whose list of children
      *            will be unsubscribed.
-     * @param options A bundle sent to the media browse service to subscribe.
+     * @param callback A callback sent to the media browse service to subscribe.
      */
-    public void unsubscribe(@NonNull String parentId, @NonNull Bundle options) {
-        if (options == null) {
-            throw new IllegalArgumentException("options are null");
+    public void unsubscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback is null");
         }
-        unsubscribeInternal(parentId, options);
+        unsubscribeInternal(parentId, callback);
     }
 
     /**
@@ -490,7 +491,7 @@
         }
     }
 
-    private void unsubscribeInternal(String parentId, Bundle options) {
+    private void unsubscribeInternal(String parentId, SubscriptionCallback callback) {
         // Check arguments.
         if (TextUtils.isEmpty(parentId)) {
             throw new IllegalArgumentException("parentId is empty.");
@@ -500,16 +501,21 @@
         Subscription sub = mSubscriptions.get(parentId);
 
         // Tell the service if necessary.
-        if (sub != null && sub.removeCallback(options) && mState == CONNECT_STATE_CONNECTED) {
+        if (mState == CONNECT_STATE_CONNECTED && sub != null) {
             try {
-                // NOTE: Do not call removeSubscriptionWithOptions when options are null. Otherwise,
-                // it will break the action of support library which expects removeSubscription will
-                // be called when options are null.
-                if (options == null) {
+                if (callback == null) {
                     mServiceBinder.removeSubscription(parentId, mServiceCallbacks);
                 } else {
-                    mServiceBinder.removeSubscriptionWithOptions(
-                            parentId, options, mServiceCallbacks);
+                    final List<SubscriptionCallback> callbacks = sub.getCallbacks();
+                    final List<Bundle> optionsList = sub.getOptionsList();
+                    for (int i = callbacks.size() - 1; i >= 0; --i) {
+                        if (callbacks.get(i) == callback) {
+                            mServiceBinder.removeSubscriptionWithOptions(
+                                    parentId, optionsList.get(i), mServiceCallbacks);
+                            callbacks.remove(i);
+                            optionsList.remove(i);
+                        }
+                    }
                 }
             } catch (RemoteException ex) {
                 // Process is crashing. We will disconnect, and upon reconnect we will
@@ -517,7 +523,8 @@
                 Log.d(TAG, "removeSubscription failed with RemoteException parentId=" + parentId);
             }
         }
-        if (sub != null && sub.isEmpty()) {
+
+        if (sub != null && (sub.isEmpty() || callback == null)) {
             mSubscriptions.remove(parentId);
         }
     }
@@ -1118,16 +1125,5 @@
             mCallbacks.add(callback);
             mOptionsList.add(options);
         }
-
-        public boolean removeCallback(Bundle options) {
-            for (int i = 0; i < mOptionsList.size(); ++i) {
-                if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
-                    mCallbacks.remove(i);
-                    mOptionsList.remove(i);
-                    return true;
-                }
-            }
-            return false;
-        }
     }
 }
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 7c9591d..acf94f4c 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -1039,6 +1039,15 @@
             }
             Settings.Secure.putStringForUser(context.getContentResolver(),
                     Settings.Secure.TV_INPUT_HIDDEN_INPUTS, builder.toString(), userId);
+
+            // Notify of the TvInputInfo changes.
+            TvInputManager tm = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
+            for (String inputId : hiddenInputIds) {
+                TvInputInfo info = tm.getTvInputInfo(inputId);
+                if (info != null) {
+                    tm.updateTvInputInfo(info);
+                }
+            }
         }
 
         /**
@@ -1069,6 +1078,15 @@
             }
             Settings.Secure.putStringForUser(context.getContentResolver(),
                     Settings.Secure.TV_INPUT_CUSTOM_LABELS, builder.toString(), userId);
+
+            // Notify of the TvInputInfo changes.
+            TvInputManager tm = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
+            for (String inputId : customLabels.keySet()) {
+                TvInputInfo info = tm.getTvInputInfo(inputId);
+                if (info != null) {
+                    tm.updateTvInputInfo(info);
+                }
+            }
         }
 
         private static void ensureValidField(String value) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 612a147..97ef6d8 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -1689,19 +1689,20 @@
         public abstract void onTune(Uri channelUri);
 
         /**
-         * Called when the application requests to tune to a given channel for TV program recording.
+         * Calls {@link #onTune(Uri)}. Override this method in order to handle domain-specific
+         * features that are only known between certain TV inputs and their clients.
          *
          * <p>The application may call this method before starting or after stopping recording, but
          * not during recording.
          *
-         * <p>The session must call {@link #notifyTuned()} if the tune request was fulfilled, or
+         * <p>The session must call {@link #notifyTuned(Uri)} if the tune request was fulfilled, or
          * {@link #notifyError(int)} otherwise.
          *
          * @param channelUri The URI of a channel.
-         * @param params Extra parameters.
-         * @hide
+         * @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
+         *            name, i.e. prefixed with a package name you own, so that different developers
+         *            will not create conflicting keys.
          */
-        @SystemApi
         public void onTune(Uri channelUri, Bundle params) {
             onTune(channelUri);
         }
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index da1002d..a5ff29f 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -91,22 +91,23 @@
      * Tunes to a given channel for TV program recording. The first tune request will create a new
      * recording session for the corresponding TV input and establish a connection between the
      * application and the session. If recording has already started in the current recording
-     * session, this method throws an exception.
+     * session, this method throws an exception. This can be used to provide domain-specific
+     * features that are only known between certain client and their TV inputs.
      *
      * <p>The application may call this method before starting or after stopping recording, but not
      * during recording.
      *
      * <p>The recording session will respond by calling
-     * {@link RecordingCallback#onTuned()} if the tune request was fulfilled, or
+     * {@link RecordingCallback#onTuned(Uri)} if the tune request was fulfilled, or
      * {@link RecordingCallback#onError(int)} otherwise.
      *
      * @param inputId The ID of the TV input for the given channel.
      * @param channelUri The URI of a channel.
-     * @param params Extra parameters.
+     * @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
+     *            name, i.e. prefixed with a package name you own, so that different developers will
+     *            not create conflicting keys.
      * @throws IllegalStateException If recording is already started.
-     * @hide
      */
-    @SystemApi
     public void tune(String inputId, Uri channelUri, Bundle params) {
         if (DEBUG) Log.d(TAG, "tune(" + channelUri + ")");
         if (TextUtils.isEmpty(inputId)) {
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index 0e7013c..d0ef37c 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -355,6 +355,19 @@
         }
     }
 
+    /**
+     * Returns object size in 64-bit integer.
+     *
+     * Though MtpObjectInfo#getCompressedSize returns the object size in 32-bit unsigned integer,
+     * this method returns the object size in 64-bit integer from the object property. Thus it can
+     * fetch 4GB+ object size correctly. If the device does not support objectSize property, it
+     * throws IOException.
+     * @hide
+     */
+    public long getObjectSizeLong(int handle, int format) throws IOException {
+        return native_get_object_size_long(handle, format);
+    }
+
     // used by the JNI code
     private long mNativeContext;
 
@@ -381,4 +394,5 @@
     private native int native_submit_event_request();
     private native MtpEvent native_reap_event_request(int handle);
     private native void native_discard_event_request(int handle);
+    private native long native_get_object_size_long(int handle, int format) throws IOException;
 }
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index f593685..ae86632 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -574,6 +574,9 @@
      * Remove the subscription.
      */
     private boolean removeSubscription(String id, ConnectionRecord connection, Bundle options) {
+        if (options == null) {
+            return connection.subscriptions.remove(id) != null;
+        }
         boolean removed = false;
         List<Bundle> optionsList = connection.subscriptions.get(id);
         if (optionsList != null) {
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 0ecb750..6e434b2 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -42,6 +42,7 @@
 #include "MtpDeviceInfo.h"
 #include "MtpStorageInfo.h"
 #include "MtpObjectInfo.h"
+#include "MtpProperty.h"
 
 using namespace android;
 
@@ -700,6 +701,42 @@
     device->discardEventRequest(seq);
 }
 
+// Returns object size in 64-bit integer. If the MTP device does not support the property, it
+// throws IOException.
+static jlong android_mtp_MtpDevice_get_object_size_long(
+        JNIEnv *env, jobject thiz, jint handle, jint format) {
+    MtpDevice* const device = get_device_from_object(env, thiz);
+    if (!device) {
+        env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice.");
+        return 0;
+    }
+
+    std::unique_ptr<MtpProperty> property(
+            device->getObjectPropDesc(MTP_PROPERTY_OBJECT_SIZE, format));
+    if (!property) {
+        env->ThrowNew(clazz_io_exception, "Failed to obtain property desc.");
+        return 0;
+    }
+
+    if (property->getDataType() != MTP_TYPE_UINT64) {
+        env->ThrowNew(clazz_io_exception, "Unexpected property data type.");
+        return 0;
+    }
+
+    if (!device->getObjectPropValue(handle, property.get())) {
+        env->ThrowNew(clazz_io_exception, "Failed to obtain property value.");
+        return 0;
+    }
+
+    const jlong object_size = static_cast<jlong>(property->getCurrentValue().u.u64);
+    if (object_size < 0) {
+        env->ThrowNew(clazz_io_exception, "Object size is too large to express as jlong.");
+        return 0;
+    }
+
+    return object_size;
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
@@ -733,6 +770,8 @@
     {"native_reap_event_request",   "(I)Landroid/mtp/MtpEvent;",
                                             (void *)android_mtp_MtpDevice_reap_event_request},
     {"native_discard_event_request", "(I)V", (void *)android_mtp_MtpDevice_discard_event_request},
+
+    {"native_get_object_size_long", "(II)J", (void *)android_mtp_MtpDevice_get_object_size_long},
 };
 
 int register_android_mtp_MtpDevice(JNIEnv *env)
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index aea8585..f21fd88 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -27,7 +27,8 @@
         <activity
             android:name="com.android.captiveportallogin.CaptivePortalLoginActivity"
             android:label="@string/action_bar_label"
-            android:theme="@style/AppTheme" >
+            android:theme="@style/AppTheme"
+            android:configChanges="keyboardHidden|orientation|screenSize" >
             <intent-filter>
                 <action android:name="android.net.conn.CAPTIVE_PORTAL"/>
                 <category android:name="android.intent.category.DEFAULT"/>
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index be08385..14609b2 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -44,7 +44,7 @@
         <activity
             android:name=".LauncherActivity"
             android:theme="@android:style/Theme.NoDisplay"
-            android:icon="@drawable/ic_files_app"
+            android:icon="@mipmap/ic_launcher_download"
             android:label="@string/downloads_label">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -55,7 +55,7 @@
         <activity
             android:name=".FilesActivity"
             android:theme="@style/DocumentsTheme"
-            android:icon="@drawable/ic_files_app"
+            android:icon="@mipmap/ic_launcher_download"
             android:label="@string/downloads_label"
             android:documentLaunchMode="intoExisting">
             <intent-filter>
diff --git a/packages/DocumentsUI/res/color/item_root_primary_text.xml b/packages/DocumentsUI/res/color/item_root_primary_text.xml
index 551245f..a5a65b2 100644
--- a/packages/DocumentsUI/res/color/item_root_primary_text.xml
+++ b/packages/DocumentsUI/res/color/item_root_primary_text.xml
@@ -15,8 +15,8 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:state_activated="true" android:color="?android:colorAccent" />
-    <item android:state_focused="false" android:state_activated="true" android:color="?android:colorAccent" />
+  <item android:state_focused="true" android:state_activated="true" android:color="@color/root_activated_color" />
+  <item android:state_focused="false" android:state_activated="true" android:color="@color/root_activated_color" />
     <item android:state_enabled="false" android:alpha="@*android:dimen/disabled_alpha_material_light" android:color="@*android:color/primary_text_default_material_light" />
     <item android:color="@*android:color/primary_text_default_material_light" />
 </selector>
diff --git a/packages/DocumentsUI/res/drawable/ic_files_app.xml b/packages/DocumentsUI/res/drawable/ic_files_app.xml
deleted file mode 100644
index 76e3ba6..0000000
--- a/packages/DocumentsUI/res/drawable/ic_files_app.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_launcher_download"
-    android:tint="?android:attr/colorControlNormal"
-    android:autoMirrored="true" />
diff --git a/packages/DocumentsUI/res/layout/dialog_file_name.xml b/packages/DocumentsUI/res/layout/dialog_file_name.xml
index 5ed476f..3a95a13 100644
--- a/packages/DocumentsUI/res/layout/dialog_file_name.xml
+++ b/packages/DocumentsUI/res/layout/dialog_file_name.xml
@@ -17,6 +17,7 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:fitsSystemWindows="true"
     android:padding="?android:attr/listPreferredItemPaddingEnd">
 
     <EditText
diff --git a/packages/DocumentsUI/res/layout/fragment_save.xml b/packages/DocumentsUI/res/layout/fragment_save.xml
index 7aac620..a889b9f 100644
--- a/packages/DocumentsUI/res/layout/fragment_save.xml
+++ b/packages/DocumentsUI/res/layout/fragment_save.xml
@@ -21,6 +21,7 @@
     android:orientation="horizontal"
     android:baselineAligned="false"
     android:gravity="center_vertical"
+    android:fitsSystemWindows="true"
     android:minHeight="?android:attr/listPreferredItemHeightSmall">
 
     <FrameLayout
diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml
index 2aee569..95c6f1f 100644
--- a/packages/DocumentsUI/res/menu/activity.xml
+++ b/packages/DocumentsUI/res/menu/activity.xml
@@ -31,61 +31,64 @@
         android:actionViewClass="android.widget.SearchView"
         android:imeOptions="actionSearch"
         android:visible="false" />
-    <item
-        android:id="@+id/menu_grid"
-        android:title="@string/menu_grid"
-        android:icon="@drawable/ic_menu_view_grid"
-        android:showAsAction="always" />
-    <item
-        android:id="@+id/menu_list"
-        android:title="@string/menu_list"
-        android:icon="@drawable/ic_menu_view_list"
-        android:showAsAction="always" />
+<!-- This group is being hidden when searching is in full bar mode-->
+    <group android:id="@+id/group_hide_when_searching">
+        <item
+            android:id="@+id/menu_grid"
+            android:title="@string/menu_grid"
+            android:icon="@drawable/ic_menu_view_grid"
+            android:showAsAction="always" />
+        <item
+            android:id="@+id/menu_list"
+            android:title="@string/menu_list"
+            android:icon="@drawable/ic_menu_view_list"
+            android:showAsAction="always" />
 
-    <item
-        android:id="@+id/menu_new_window"
-        android:title="@string/menu_new_window"
-        android:alphabeticShortcut="n"
-        android:showAsAction="never"
-        android:visible="false" />
-    <item
-        android:id="@+id/menu_create_dir"
-        android:title="@string/menu_create_dir"
-        android:icon="@drawable/ic_menu_new_folder"
-        android:alphabeticShortcut="e"
-        android:showAsAction="never"
-        android:visible="false" />
-    <item
-        android:id="@+id/menu_paste_from_clipboard"
-        android:title="@string/menu_paste_from_clipboard"
-        android:alphabeticShortcut="v"
-        android:showAsAction="never"
-        android:visible="false" />
-    <!-- Copy action is defined in mode_directory.xml -->
-    <item
-        android:id="@+id/menu_sort"
-        android:title="@string/menu_sort"
-        android:icon="@drawable/ic_menu_sortby"
-        android:showAsAction="ifRoom">
-        <menu>
-            <item
-                android:id="@+id/menu_sort_name"
-                android:title="@string/sort_name" />
-            <item
-                android:id="@+id/menu_sort_date"
-                android:title="@string/sort_date" />
-            <item
-                android:id="@+id/menu_sort_size"
-                android:title="@string/sort_size" />
-        </menu>
-    </item>
-    <item
-        android:id="@+id/menu_file_size"
-        android:showAsAction="never"
-        android:visible="false" />
-    <item
-        android:id="@+id/menu_settings"
-        android:title="@string/menu_settings"
-        android:showAsAction="never"
-        android:visible="false" />
+        <item
+            android:id="@+id/menu_new_window"
+            android:title="@string/menu_new_window"
+            android:alphabeticShortcut="n"
+            android:showAsAction="never"
+            android:visible="false" />
+        <item
+            android:id="@+id/menu_create_dir"
+            android:title="@string/menu_create_dir"
+            android:icon="@drawable/ic_menu_new_folder"
+            android:alphabeticShortcut="e"
+            android:showAsAction="never"
+            android:visible="false" />
+        <item
+            android:id="@+id/menu_paste_from_clipboard"
+            android:title="@string/menu_paste_from_clipboard"
+            android:alphabeticShortcut="v"
+            android:showAsAction="never"
+            android:visible="false" />
+        <!-- Copy action is defined in mode_directory.xml -->
+        <item
+            android:id="@+id/menu_sort"
+            android:title="@string/menu_sort"
+            android:icon="@drawable/ic_menu_sortby"
+            android:showAsAction="ifRoom">
+            <menu>
+                <item
+                    android:id="@+id/menu_sort_name"
+                    android:title="@string/sort_name" />
+                <item
+                    android:id="@+id/menu_sort_date"
+                    android:title="@string/sort_date" />
+                <item
+                    android:id="@+id/menu_sort_size"
+                    android:title="@string/sort_size" />
+            </menu>
+        </item>
+        <item
+            android:id="@+id/menu_file_size"
+            android:showAsAction="never"
+            android:visible="false" />
+        <item
+            android:id="@+id/menu_settings"
+            android:title="@string/menu_settings"
+            android:showAsAction="never"
+            android:visible="false" />
+    </group>
 </menu>
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-hdpi/ic_launcher_download.png
similarity index 100%
rename from packages/DocumentsUI/res/drawable-hdpi/ic_launcher_download.png
rename to packages/DocumentsUI/res/mipmap-hdpi/ic_launcher_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-mdpi/ic_launcher_download.png
similarity index 100%
rename from packages/DocumentsUI/res/drawable-mdpi/ic_launcher_download.png
rename to packages/DocumentsUI/res/mipmap-mdpi/ic_launcher_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-xhdpi/ic_launcher_download.png
similarity index 100%
rename from packages/DocumentsUI/res/drawable-xhdpi/ic_launcher_download.png
rename to packages/DocumentsUI/res/mipmap-xhdpi/ic_launcher_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-xxhdpi/ic_launcher_download.png
similarity index 100%
rename from packages/DocumentsUI/res/drawable-xxhdpi/ic_launcher_download.png
rename to packages/DocumentsUI/res/mipmap-xxhdpi/ic_launcher_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxxhdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-xxxhdpi/ic_launcher_download.png
similarity index 100%
rename from packages/DocumentsUI/res/drawable-xxxhdpi/ic_launcher_download.png
rename to packages/DocumentsUI/res/mipmap-xxxhdpi/ic_launcher_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 5abb9d7..a3fdd78 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Kon nie dokument hernoem nie"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige lêers is omgeskakel"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot jou data, insluitend foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Moenie weer vra nie"</string>
     <string name="allow" msgid="7225948811296386551">"Laat toe"</string>
     <string name="deny" msgid="2081879885755434506">"Weier"</string>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index b77b82cc..df73bed 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ሰነዱን ዳግም መሰየም አልተሳካም"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"አንዳንድ ፋይሎች ተለውጠዋል"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> በ<xliff:g id="STORAGE"><i>^3</i></xliff:g> ላይ የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መደረሻ ይሰጠው?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"በ<xliff:g id="STORAGE"><i>^2</i></xliff:g> ላይ ያሉትን ፎቶዎች እና ቪዲዮዎች ጨምሮ የውሂብዎ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጥ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"ዳግም አትጠይቅ"</string>
     <string name="allow" msgid="7225948811296386551">"ይፍቀዱ"</string>
     <string name="deny" msgid="2081879885755434506">"ያስተባብሉ"</string>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 1625043..d92eb5f 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -139,6 +139,7 @@
     <string name="rename_error" msgid="4203041674883412606">"أخفقت إعادة تسمية المستند."</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"تم تحويل بعض الملفات"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"هل تريد منح التطبيق <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى الدليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> على <xliff:g id="STORAGE"><i>^3</i></xliff:g>؟"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"هل تريد منح <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى بياناتك، بما في ذلك الصور ومقاطع الفيديو على <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"عدم السؤال مرة أخرى"</string>
     <string name="allow" msgid="7225948811296386551">"السماح"</string>
     <string name="deny" msgid="2081879885755434506">"رفض"</string>
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 0f0eda4..632fa6b 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Sənəd adını dəyişmək uğursuz oldu"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bəzi fayllar konvertasiya edilib"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> yaddaşında <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> yaddaşında foto və videolar daxil olmaqla datanıza <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təmin edilsin?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Bir daha soruşmayın"</string>
     <string name="allow" msgid="7225948811296386551">"İcazə verin"</string>
     <string name="deny" msgid="2081879885755434506">"Rədd et"</string>
diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
index 7bbf942..2d679ea 100644
--- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
@@ -118,6 +118,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Preimenovanje dokumenta nije uspelo"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke datoteke su konvertovane"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li da aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobrite pristup direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na memorijskom prostoru <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite da li da dozvolite da aplikacija <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristupa podacima, uključujući slike i video snimke, na lokaciji <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string>
     <string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
     <string name="deny" msgid="2081879885755434506">"Odbij"</string>
diff --git a/packages/DocumentsUI/res/values-be-rBY/strings.xml b/packages/DocumentsUI/res/values-be-rBY/strings.xml
index 4621d9b..abd4679 100644
--- a/packages/DocumentsUI/res/values-be-rBY/strings.xml
+++ b/packages/DocumentsUI/res/values-be-rBY/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Не атрымалася перайменаваць дакумент"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некаторыя файлы былі сканвертаваныя"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да дырэкторыі <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> у <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Даць <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да вашых даных, у тым ліку фатаграфій і відэа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Больш не пытацца"</string>
     <string name="allow" msgid="7225948811296386551">"Дазволіць"</string>
     <string name="deny" msgid="2081879885755434506">"Забараніць"</string>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index 329f92f..4822adb 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Преименуването на документа не бе успешно"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Някои файлове бяха преобразувани"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ в/ъв <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до данните ви в хранилището (<xliff:g id="STORAGE"><i>^2</i></xliff:g>), включително снимки и видеоклипове?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Без повторно питане"</string>
     <string name="allow" msgid="7225948811296386551">"Разрешаване"</string>
     <string name="deny" msgid="2081879885755434506">"Отказване"</string>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index 936e2dd..5709692 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -32,7 +32,7 @@
     <string name="menu_share" msgid="3075149983979628146">"শেয়ার করুন"</string>
     <string name="menu_delete" msgid="8138799623850614177">"মুছুন"</string>
     <string name="menu_select_all" msgid="8323579667348729928">"সবগুলি নির্বাচন করুন"</string>
-    <string name="menu_copy" msgid="3612326052677229148">"এতে অনুলিপি করুন…"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"এতে কপি করুন…"</string>
     <string name="menu_move" msgid="1828090633118079817">"এতে সরান..."</string>
     <string name="menu_new_window" msgid="1226032889278727538">"নতুন উইন্ডো"</string>
     <string name="menu_copy_to_clipboard" msgid="489311381979634291">"প্রতিলিপি করুন"</string>
@@ -42,7 +42,7 @@
     <string name="menu_file_size_show" msgid="3240323619260823076">"ফাইলের আকার দেখান"</string>
     <string name="menu_file_size_hide" msgid="8881975928502581042">"ফাইলের আকার লুকান"</string>
     <string name="button_select" msgid="527196987259139214">"নির্বাচন করুন"</string>
-    <string name="button_copy" msgid="8706475544635021302">"অনুলিপি করুন"</string>
+    <string name="button_copy" msgid="8706475544635021302">"কপি করুন"</string>
     <string name="button_move" msgid="2202666023104202232">"সরান"</string>
     <string name="button_dismiss" msgid="3714065566893946085">"খারিজ করুন"</string>
     <string name="button_retry" msgid="4392027584153752797">"আবার চেষ্টা করুন"</string>
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"দস্তাবেজের পুনঃনামকরণ ব্যর্থ হয়েছে৷"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"কিছু ফাইল রূপান্তরিত হয়েছে"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="STORAGE"><i>^3</i></xliff:g> এ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার মঞ্জুরি দিতে চান?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> এ থাকা ফটো ও ভিডিওগুলি সমেত <xliff:g id="APPNAME"><b>^1</b></xliff:g> কে আপনার ডেটা অ্যাক্সেস করার অনুমতি দেবেন?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"আর জিজ্ঞাসা করবেন না"</string>
     <string name="allow" msgid="7225948811296386551">"অনুমতি দিন"</string>
     <string name="deny" msgid="2081879885755434506">"আস্বীকার করুন"</string>
diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
index d23c884..9c94a05 100644
--- a/packages/DocumentsUI/res/values-bs-rBA/strings.xml
+++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
@@ -118,6 +118,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Nije uspjelo preimenovanje dokumenta"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke od datoteka su pretvorene"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Omogućiti <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li odobriti aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup svojim podacima, uključujući fotografije i video zapise, na <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string>
     <string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
     <string name="deny" msgid="2081879885755434506">"Odbijte"</string>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 044350a..4ecec9f 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"No s\'ha pogut canviar el nom del document"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"S\'han convertit alguns fitxers"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de l\'emmagatzematge <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés a les dades de l\'emmagatzematge <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incloses les fotos i els vídeos?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"No m\'ho demanis més"</string>
     <string name="allow" msgid="7225948811296386551">"Permet"</string>
     <string name="deny" msgid="2081879885755434506">"Denega"</string>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index ca6f3f1..3c6e81d 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Dokument se nepodařilo přejmenovat."</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Některé soubory byly převedeny"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložišti <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup ke svým datům v úložišti <xliff:g id="STORAGE"><i>^2</i></xliff:g>, včetně fotek a videí?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Příště se neptat"</string>
     <string name="allow" msgid="7225948811296386551">"Povolit"</string>
     <string name="deny" msgid="2081879885755434506">"Odepřít"</string>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index c4e7770..679506b 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Dokumentet kunne ikke omdøbes"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nogle filer er konverteret"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til mappen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til dine data, herunder billeder og videoer på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Spørg ikke igen"</string>
     <string name="allow" msgid="7225948811296386551">"Tillad"</string>
     <string name="deny" msgid="2081879885755434506">"Afvis"</string>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index 766222c..b48afb0 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Dokument konnte nicht umbenannt werden"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Einige Dateien wurden konvertiert"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> auf <xliff:g id="STORAGE"><i>^3</i></xliff:g> geben?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Möchtest du <xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf deine Daten auf <xliff:g id="STORAGE"><i>^2</i></xliff:g> geben, einschließlich Fotos und Videos?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Nicht mehr fragen"</string>
     <string name="allow" msgid="7225948811296386551">"Zulassen"</string>
     <string name="deny" msgid="2081879885755434506">"Ablehnen"</string>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 3bbcf776..3872c40 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Αποτυχία μετονομασίας εγγράφου"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Ορισμένα αρχεία μετατράπηκαν"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Να εκχωρηθεί στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> πρόσβαση στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^3</i></xliff:g>;"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Θέλετε να εκχωρήσετε πρόσβαση στα δεδομένα σας στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g>, συμπεριλαμβανομένων των φωτογραφιών και των βίντεό σας, στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^2</i></xliff:g>;"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Να μην ερωτηθώ ξανά"</string>
     <string name="allow" msgid="7225948811296386551">"Να επιτρέπεται"</string>
     <string name="deny" msgid="2081879885755434506">"Άρνηση"</string>
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
index d28b675..8a56f6c 100644
--- a/packages/DocumentsUI/res/values-en-rAU/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
     <string name="allow" msgid="7225948811296386551">"Allow"</string>
     <string name="deny" msgid="2081879885755434506">"Deny"</string>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index d28b675..8a56f6c 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
     <string name="allow" msgid="7225948811296386551">"Allow"</string>
     <string name="deny" msgid="2081879885755434506">"Deny"</string>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index d28b675..8a56f6c 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
     <string name="allow" msgid="7225948811296386551">"Allow"</string>
     <string name="deny" msgid="2081879885755434506">"Deny"</string>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 6d847b5..3f36f41 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"No se pudo cambiar el nombre del documento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se convirtieron algunos archivos"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"¿Otorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> en <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Quieres otorgar acceso a la app de <xliff:g id="APPNAME"><b>^1</b></xliff:g> a tus datos, incluidas tus fotos y videos en <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Denegar"</string>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index 15b5694..a0da06c 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Error al cambiar el nombre del documento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se han convertido algunos archivos"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> (<xliff:g id="STORAGE"><i>^3</i></xliff:g>)?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda a tus datos, incluidos los vídeos y las fotos de <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Denegar"</string>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index ed60aa9..d49b320 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Dokumendi ümbernimetamine ebaõnnestus"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Mõned failid teisendati"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> salvestusruumis <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs teie andmetele (sh fotod ja videod) salvestusruumis <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ära enam küsi"</string>
     <string name="allow" msgid="7225948811296386551">"Luba"</string>
     <string name="deny" msgid="2081879885755434506">"Keela"</string>
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index f3d68b0d..085f148 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Ezin izan zaio aldatu izena dokumentuari"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Artxibo batzuk bihurtu dira"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="STORAGE"><i>^3</i></xliff:g> unitateko <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktorioa atzitzeko baimena eman nahi diozu?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari zure datuak atzitzea baimendu nahi diozu, besteak beste, <xliff:g id="STORAGE"><i>^2</i></xliff:g> biltegian dituzun argazkiak eta bideoak?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ez galdetu berriro"</string>
     <string name="allow" msgid="7225948811296386551">"Onartu"</string>
     <string name="deny" msgid="2081879885755434506">"Ukatu"</string>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index 80e1aa8..114c7d0 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"نام سند تغییر نکرد"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"بعضی از فایل‌ها تبدیل شدند"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه داده شود به فهرست راهنمای <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> در <xliff:g id="STORAGE"><i>^3</i></xliff:g> دسترسی داشته باشد؟"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه می‌دهید به داده‌هایتان دسترسی پیدا کند، از جمله عکس‌ها و ویدیوهایتان در <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"دوباره سؤال نشود"</string>
     <string name="allow" msgid="7225948811296386551">"ارزیابی‌شده"</string>
     <string name="deny" msgid="2081879885755434506">"اجازه ندارد"</string>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index 279aad7..46f863f 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Dokumentin nimen muuttaminen epäonnistui."</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Joitakin tiedostoja muunnettiin."</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^3</i></xliff:g> olevan hakemiston <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> käyttöoikeus?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^2</i></xliff:g> olevien tietojesi, mukaan lukien valokuviesi ja videoidesi, käyttöoikeus?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Älä kysy uudestaan"</string>
     <string name="allow" msgid="7225948811296386551">"Salli"</string>
     <string name="deny" msgid="2081879885755434506">"Kiellä"</string>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index 347a3f2..b78b10e 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Impossible de renommer le document"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sur <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Voulez-vous accorder l\'accès à vos données à <xliff:g id="APPNAME"><b>^1</b></xliff:g>, y compris vos photos et vos vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ne plus me demander"</string>
     <string name="allow" msgid="7225948811296386551">"Autoriser"</string>
     <string name="deny" msgid="2081879885755434506">"Refuser"</string>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index 6030bde..63e28bf 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Échec du changement de nom du document."</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" sur <xliff:g id="STORAGE"><i>^3</i></xliff:g> ?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à vos données, y compris les photos et les vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ne plus demander"</string>
     <string name="allow" msgid="7225948811296386551">"Autoriser"</string>
     <string name="deny" msgid="2081879885755434506">"Refuser"</string>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index 58181f8..9ce9ebd 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Non se puido cambiar o nome do documento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Convertéronse algúns ficheiros"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Queres outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no almacenamento de <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Queres darlle acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> aos teus datos almacenados en <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incluídos vídeos e fotos?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Non preguntar de novo"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Rexeitar"</string>
diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
index 2cce5a3..6c2bb3e 100644
--- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"દસ્તાવેજનું નામ બદલવામાં નિષ્ફળ થયાં"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"કેટલીક ફાઇલો રૂપાંતરિત કરી હતી"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^3</i></xliff:g> પર <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^2</i></xliff:g> પર ફોટા અને વિડિઓઝ સહિત તમારા ડેટાની અ‍ૅક્સેસ આપીએ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"ફરીથી પૂછશો નહીં"</string>
     <string name="allow" msgid="7225948811296386551">"મંજૂરી આપો"</string>
     <string name="deny" msgid="2081879885755434506">"નકારો"</string>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index 9f57f0b..9c27556 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"दस्‍तावेज़ का नाम बदलना विफल रहा"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"कुछ फ़ाइलें रूपांतरित हो गई थीं"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^3</i></xliff:g> पर <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस दें?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^2</i></xliff:g> पर मौजूद फ़ोटो और वीडियो सहित, अपने डेटा का एक्सेस प्रदान करें?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"फिर से ना पूछें"</string>
     <string name="allow" msgid="7225948811296386551">"अनुमति दें"</string>
     <string name="deny" msgid="2081879885755434506">"अस्वीकारें"</string>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 0d42d5d..58e709b 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -118,6 +118,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Naziv dokumenta nije promijenjen"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke su datoteke konvertirane"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na pohrani <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dopustiti pristup podacima, uključujući fotografije i videozapise na vanjskoj pohrani (<xliff:g id="STORAGE"><i>^2</i></xliff:g>)?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Više me ne pitaj"</string>
     <string name="allow" msgid="7225948811296386551">"Dopusti"</string>
     <string name="deny" msgid="2081879885755434506">"Odbij"</string>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index 37bfcfa..1936214 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Nem sikerült átnevezni a dokumentumot"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Egyes fájlokat konvertált a rendszer"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz itt: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára az Ön adataihoz, beleértve a következő tárhelyen található képekhez és videókhoz: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ne jelenjen meg többé"</string>
     <string name="allow" msgid="7225948811296386551">"Engedélyezés"</string>
     <string name="deny" msgid="2081879885755434506">"Elutasítás"</string>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 22e44b0f..57af718 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Չհաջողվեց վերանվանել փաստաթուղթը"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Որոշ ֆայլեր փոխարկվել են"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ի <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ում պահվող ձեր տվյալները, այդ թվում նաև լուսանկարները և տեսանյութերը, օգտագործելու թույլտվություն:"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Այլևս չհարցնել"</string>
     <string name="allow" msgid="7225948811296386551">"Թույլատրել"</string>
     <string name="deny" msgid="2081879885755434506">"Մերժել"</string>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index f9aae9d..6621c9171 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Gagal mengganti nama dokumen"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Beberapa file dikonversi"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke data Anda, termasuk foto dan video, di <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string>
     <string name="allow" msgid="7225948811296386551">"Izinkan"</string>
     <string name="deny" msgid="2081879885755434506">"Tolak"</string>
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index a2a0d9b..4265606 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Ekki tókst að endurnefna skjalið"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sumum skrám var umbreytt"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> á <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að gögnunum þínum, þar á meðal myndum og myndskeiðum, á <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ekki spyrja aftur"</string>
     <string name="allow" msgid="7225948811296386551">"Leyfa"</string>
     <string name="deny" msgid="2081879885755434506">"Hafna"</string>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index ddede45..7599180 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Ridenominazione documento non riuscita"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alcuni file sono stati convertiti"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> su <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso ai tuoi dati, inclusi video e foto, sull\'unità <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Non chiedermelo più"</string>
     <string name="allow" msgid="7225948811296386551">"Consenti"</string>
     <string name="deny" msgid="2081879885755434506">"Nega"</string>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index e2658c3..2e2020c 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ניסיון שינוי שם המסמך נכשל"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"קבצים מסוימים הומרו"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לספריה <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> באחסון <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לנתונים שלך, כולל תמונות וסרטונים, השמורים ב<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"אל תשאל שוב"</string>
     <string name="allow" msgid="7225948811296386551">"אפשר"</string>
     <string name="deny" msgid="2081879885755434506">"דחה"</string>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index 3cad318..1ba405f 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ドキュメントの名前を変更できませんでした"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"一部のファイルが変換されました"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"「<xliff:g id="STORAGE"><i>^3</i></xliff:g>」の「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」ディレクトリに「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」へのアクセスを許可しますか?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>の写真や動画などのデータへのアクセスを「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」に許可しますか?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"今後表示しない"</string>
     <string name="allow" msgid="7225948811296386551">"許可"</string>
     <string name="deny" msgid="2081879885755434506">"拒否"</string>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index afd4198..c1624e3 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"დოკუმენტის გადარქმევა ვერ მოხერხდა"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ზოგიერთი ფაილი გარდაქმნილია"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ის დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ზე არსებულ მონაცემებზე, მათ შორის, ფოტოებსა და ვიდეოებზე, წვდომის უფლებით?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"აღარ მკითხოთ"</string>
     <string name="allow" msgid="7225948811296386551">"უფლების მიცემა"</string>
     <string name="deny" msgid="2081879885755434506">"აკრძალვა"</string>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 21a8260..904ca5d 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Құжат қайта аталмады"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Кейбір файлдар түрлендірілді"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="STORAGE"><i>^3</i></xliff:g> қоймасындағы <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына өтуге рұқсат беру керек пе?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> <xliff:g id="STORAGE"><i>^2</i></xliff:g> қоймасындағы деректерге, соның ішінде, фотосуреттерге және бейнелерге қатынас беру керек пе?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Қайта сұралмасын"</string>
     <string name="allow" msgid="7225948811296386551">"Рұқсат беру"</string>
     <string name="deny" msgid="2081879885755434506">"Бас тарту"</string>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index 5a049add..ca0fa4c 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"បានបរាជ័យក្នុងការប្តូរឈ្មោះឯកសារ"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ឯកសារមួយចំនួនត្រូវបានបម្លែង"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> នៅលើ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ផ្តល់សិទ្ធិអនុញ្ញាតដល់ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ដើម្បីចូលដំណើរការទិន្នន័យរបស់អ្នក រាប់បញ្ចូលទាំងរូបថត និងវីដេអូ នៅលើ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ឬទេ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"កុំសួរទៀត"</string>
     <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត​"</string>
     <string name="deny" msgid="2081879885755434506">"បដិសេធ"</string>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index 924b14a..6287274 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ಡಾಕ್ಯುಮೆಂಟ್ ಮರುಹೆಸರಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ಕೆಲವು ಫೈಲ್‌ಗಳನ್ನು ಪರಿವರ್ತಿಸಲಾಗಿದೆ"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> ರಲ್ಲಿ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ಸಂಗ್ರಹಣೆಯಲ್ಲಿನ ಪೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string>
     <string name="allow" msgid="7225948811296386551">"ಅನುಮತಿಸು"</string>
     <string name="deny" msgid="2081879885755434506">"ನಿರಾಕರಿಸು"</string>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index df0cbf2..1b553b5 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"문서 이름을 변경하지 못했습니다."</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"일부 파일이 변환되었습니다."</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>이(가) <xliff:g id="STORAGE"><i>^3</i></xliff:g>에서 <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>에서 사진, 동영상 등 <xliff:g id="STORAGE"><i>^2</i></xliff:g>의 내 데이터에 액세스하도록 허용하시겠습니까?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"다시 묻지 않음"</string>
     <string name="allow" msgid="7225948811296386551">"허용"</string>
     <string name="deny" msgid="2081879885755434506">"거부"</string>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index 84bc37f..f4981b9 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Документтин аталышы өзгөртүлбөй калды"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Айрым файлдардын форматы өзгөртүлдү"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^3</i></xliff:g> түзмөгүндөгү <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> папканы пайдалануу мүмкүнчүлүгү берилсинби?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^2</i></xliff:g> түзмөгүндөгү дайындарыңыз, сүрөттөрүңүз жана видеолоруңузду пайдалануу мүмкүнчүлүгү берилсинби?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Экинчи суралбасын"</string>
     <string name="allow" msgid="7225948811296386551">"Уруксат берүү"</string>
     <string name="deny" msgid="2081879885755434506">"Жок"</string>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 4c891aa..4203241 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ປ່ຽນຊື່ເອກະສານບໍ່ສຳເລັດ"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ປ່ຽນແປງບາງໄຟລ໌ແລ້ວ"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"ອະນຸຍາດສິດເຂົ້າເຖິງໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເພື່ອເຂົ້າໄດເຣກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ຢູ່ <xliff:g id="STORAGE"><i>^3</i></xliff:g> ບໍ?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ອະນຸມັດໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເຂົ້າເຖິງຂໍ້ມູນຂອງທ່ານ ເຊິ່ງຮວມເຖິງຮູບພາບ ແລະ ວິດີໂອໃນ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ໄດ້ບໍ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"ບໍ່ຕ້ອງຖາມຄືນ"</string>
     <string name="allow" msgid="7225948811296386551">"ອະນຸຍາດ"</string>
     <string name="deny" msgid="2081879885755434506">"ປະ​ຕິ​ເສດ"</string>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index 8aec2d4..5114854 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Nepavyko pervardyti dokumento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Kai kurie failai buvo konvertuoti"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Suteikti programai „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie duomenų, įskaitant nuotraukas ir vaizdo įrašus, <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Daugiau neklausti"</string>
     <string name="allow" msgid="7225948811296386551">"Leisti"</string>
     <string name="deny" msgid="2081879885755434506">"Atmesti"</string>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index be2f0b7..8ee161d 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -118,6 +118,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Neizdevās pārdēvēt dokumentu"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Daži faili tika pārveidoti."</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> šajā krātuvē: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt jūsu datiem, tostarp fotoattēliem un videoklipiem, šajā krātuvē: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Turpmāk vairs nejautāt"</string>
     <string name="allow" msgid="7225948811296386551">"Atļaut"</string>
     <string name="deny" msgid="2081879885755434506">"Noraidīt"</string>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index e9c7f3f..5fb64f1 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Не успеа да се преименува документот"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некои датотеки беа конвертирани"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Овозможете пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се овозможи пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до вашите податоци, вклучувајќи фотографии и видеа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Не прашувај повторно"</string>
     <string name="allow" msgid="7225948811296386551">"Дозволи"</string>
     <string name="deny" msgid="2081879885755434506">"Одбиј"</string>
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index e71e62a..afb26a0 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ഡോക്യുമെന്റിന്റെ പേരുമാറ്റുന്നത് പരാജയപ്പെട്ടു"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ചില ഫയലുകൾ പരിവർത്തനം ചെയ്യപ്പെട്ടു"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> സ്റ്റോറേജിലെ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്റ്ററിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> സ്റ്റോറേജിലെ ഫോട്ടോകളും വീഡിയോകളും ഉൾപ്പെടെ, നിങ്ങളുടെ ഡാറ്റയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ്സ് അനുവദിക്കണോ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
     <string name="allow" msgid="7225948811296386551">"അനുവദിക്കുക"</string>
     <string name="deny" msgid="2081879885755434506">"നിരസിക്കുക"</string>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index 64cc2a8..2890908 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Баримт бичгийн нэрийн өөрчилж чадсангүй"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Зарим файлыг хөрвүүлсэн"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g>-д байгаа <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандахыг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д зөвшөөрөх үү?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>-д байгаа зураг, видео гэх мэт таны өгөгдөлд <xliff:g id="APPNAME"><b>^1</b></xliff:g> хандахыг зөвшөөрөх үү?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Дахин бүү асуу"</string>
     <string name="allow" msgid="7225948811296386551">"Зөвшөөрөх"</string>
     <string name="deny" msgid="2081879885755434506">"Татгалзах"</string>
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index 415eda8..e850b26 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"दस्तऐवज पुनर्नामित करण्‍यात अयशस्वी झाले"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"काही फायली रूपांतरित केल्या होत्या"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> वर <xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकेवर प्रवेशाची मंजूरी द्यायची?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="STORAGE"><i>^2</i></xliff:g> वर फोटो आणि व्हिडिओंसह, आपल्या डेटामध्ये प्रवेश करण्याची मंजूरी द्यायची?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"पुन्हा विचारू नका"</string>
     <string name="allow" msgid="7225948811296386551">"अनुमती द्या"</string>
     <string name="deny" msgid="2081879885755434506">"नकार द्या"</string>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index c5f4771..374cbb0 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Gagal menamakan semula dokumen"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sesetengah fail telah ditukarkan"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada data anda, termasuk foto dan video pada <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string>
     <string name="allow" msgid="7225948811296386551">"Benarkan"</string>
     <string name="deny" msgid="2081879885755434506">"Nafi"</string>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index bdfd1a2..80afcfb 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"စာရွက်စာတမ်းကို အမည်ပြောင်းခြင်း မအောင်မြင်ပါ"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"အချို့ဖိုင်များကို ပြောင်းလဲထားသည်"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ကို <xliff:g id="STORAGE"><i>^3</i></xliff:g> ရှိ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> လမ်းညွှန်အား အသုံးပြုခွင့်ပေးမလား။"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ရှိဓာတ်ပုံများနှင့် ဗီဒီယိုများအပါအဝင် သင့်ဒေတာများကို <xliff:g id="APPNAME"><b>^1</b></xliff:g> အားအသုံးပြုခွင့်ပေးမလား။"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"နောက်ထပ်မမေးပါနှင့်"</string>
     <string name="allow" msgid="7225948811296386551">"ခွင့်ပြုသည်"</string>
     <string name="deny" msgid="2081879885755434506">"ငြင်းပယ်သည်"</string>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 5922d1c..8349a13 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Kunne ikke gi dokumentet nytt navn"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Noen filer er konvertert"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til dataene dine – inkludert bilder og videoer – på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ikke spør igjen"</string>
     <string name="allow" msgid="7225948811296386551">"Tillat"</string>
     <string name="deny" msgid="2081879885755434506">"Avslå"</string>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index 4bc814b..a110742 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"कागजात पुन: नामाकरण गर्न असफल भयो"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"केही फाइलहरू परिवर्तन गरिएका थिए"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^3</i></xliff:g> मा भएको <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामा पहुँच गर्न अनुमति दिने हो?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^2</i></xliff:g> मा भएका तस्बिर र भिडियोहरू लगायत तपाईँको डेटामा पहुँच गर्नका लागि अनुमति दिने हो?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"फेरि नसोध्नुहोस्"</string>
     <string name="allow" msgid="7225948811296386551">"अनुमति दिनुहोस्"</string>
     <string name="deny" msgid="2081879885755434506">"अस्वीकार गर्नुहोस्"</string>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index f1b3ed7..27796cf 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Kan naam van document niet wijzigen"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige bestanden zijn geconverteerd"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot je gegevens, waaronder foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Niet meer vragen"</string>
     <string name="allow" msgid="7225948811296386551">"Toestaan"</string>
     <string name="deny" msgid="2081879885755434506">"Weigeren"</string>
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index f9f9412..503bc0d 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ਦਸਤਾਵੇਜ਼ ਦਾ ਮੁੜ-ਨਾਮਕਰਨ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ਕੁਝ ਫ਼ਾਈਲਾਂ ਤਬਦੀਲ ਕੀਤੀਆਂ ਗਈਆਂ ਸਨ"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^3</i></xliff:g> \'ਤੇ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^2</i></xliff:g> \'ਤੇ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਸਮੇਤ, ਤੁਹਾਡੇ ਡੈਟੇ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
     <string name="allow" msgid="7225948811296386551">"ਆਗਿਆ ਦਿਓ"</string>
     <string name="deny" msgid="2081879885755434506">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 7a35bc24..7f0b274 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Nie udało się zmienić nazwy dokumentu"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektóre pliki zostały przekonwertowane"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> w pamięci masowej <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do Twoich danych, w tym zdjęć i filmów, zapisanych w pamięci <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Nie pytaj ponownie"</string>
     <string name="allow" msgid="7225948811296386551">"Zezwól"</string>
     <string name="deny" msgid="2081879885755434506">"Odmów"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index b765cd0..d34b7b6 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Negar"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 1edd1c0..7c82410 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Falha ao mudar o nome do documento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns ficheiros foram convertidos"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no(a) <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no(a) <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Recusar"</string>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index b765cd0..d34b7b6 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Negar"</string>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 10f6aee..54458f1 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -118,6 +118,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Documentul nu a putut fi redenumit"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Unele fișiere au fost convertite"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> accesul la directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de pe <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să vă acceseze datele, inclusiv fotografiile și videoclipurile, de pe <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Nu mai întreba"</string>
     <string name="allow" msgid="7225948811296386551">"Permiteți"</string>
     <string name="deny" msgid="2081879885755434506">"Refuzați"</string>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index d9f40097..2eda9ec 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Не удалось переименовать документ"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Формат некоторых файлов изменен"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" на устройстве \"<xliff:g id="STORAGE"><i>^3</i></xliff:g>\"?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к вашим данным, включая фото и видео, на носителе: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Больше не спрашивать"</string>
     <string name="allow" msgid="7225948811296386551">"Разрешить"</string>
     <string name="deny" msgid="2081879885755434506">"Отклонить"</string>
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index 41ee2260..1dc9a2b 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ලේඛනය යළි නම් කිරීම අසාර්ථක විය"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"සමහර ගොනු පරිවර්තනය කරන ලදී"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> හට <xliff:g id="STORAGE"><i>^3</i></xliff:g> මත <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ප්‍රවේශය දෙන්නද?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> හි, ඡායාරූප සහ වීඩියෝ ඇතුළුව, ඔබේ දත්තවලට <xliff:g id="APPNAME"><b>^1</b></xliff:g> හට ප්‍රවේශය ලබා දෙන්නද?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"නැවත අසන්න එපා"</string>
     <string name="allow" msgid="7225948811296386551">"අවසර දෙන්න"</string>
     <string name="deny" msgid="2081879885755434506">"ප්‍රතික්ෂේප කරන්න"</string>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index 518093c..da91574 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Premenovanie dokumentu zlyhalo"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektoré súbory boli konvertované"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložisku <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> udeliť prístup k dátam (vrátane fotiek a videí) v úložisku <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Nabudúce sa nepýtať"</string>
     <string name="allow" msgid="7225948811296386551">"Povoliť"</string>
     <string name="deny" msgid="2081879885755434506">"Zamietnuť"</string>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index 39cfed7..9a7b477 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Dokumenta ni bilo mogoče preimenovati"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nekatere datoteke so bile pretvorjene"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v shrambi <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Odobrite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostop do podatkov, vključno s fotografijami in videoposnetki, v shrambi <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ne sprašuj več"</string>
     <string name="allow" msgid="7225948811296386551">"Dovoli"</string>
     <string name="deny" msgid="2081879885755434506">"Zavrni"</string>
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index f5ebbbc..6b41c60 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Riemërtimi i dokumentit dështoi"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Disa skedarë u konvertuan"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Jepi aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> në <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te të dhënat, duke përfshirë fotografitë dhe videot, në <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Mos pyet përsëri"</string>
     <string name="allow" msgid="7225948811296386551">"Lejo"</string>
     <string name="deny" msgid="2081879885755434506">"Moho"</string>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 6a6488e..b6ccf45 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -118,6 +118,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Преименовање документа није успело"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Неке датотеке су конвертоване"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Желите ли да апликацији <xliff:g id="APPNAME"><b>^1</b></xliff:g> одобрите приступ директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на меморијском простору <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Желите да ли да дозволите да апликација <xliff:g id="APPNAME"><b>^1</b></xliff:g> приступа подацима, укључујући слике и видео снимке, на локацији <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Не питај поново"</string>
     <string name="allow" msgid="7225948811296386551">"Дозволи"</string>
     <string name="deny" msgid="2081879885755434506">"Одбиј"</string>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 8b55b22..67bbfdf 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Det gick inte att byta namn på dokumentet"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Vissa filer konverterades"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till din data (inklusive foton och videor) på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Fråga inte igen"</string>
     <string name="allow" msgid="7225948811296386551">"Tillåt"</string>
     <string name="deny" msgid="2081879885755434506">"Neka"</string>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index 482c7ec..168b63a 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Imeshindwa kubadilisha jina la hati"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Baadhi ya faili zimebadilishwa muundo"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kwenye <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie data yako, ikiwa ni pamoja na picha na video kwenye <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Usiniulize tena"</string>
     <string name="allow" msgid="7225948811296386551">"Ruhusu"</string>
     <string name="deny" msgid="2081879885755434506">"Kataza"</string>
diff --git a/packages/DocumentsUI/res/values-sw720dp/colors.xml b/packages/DocumentsUI/res/values-sw720dp/colors.xml
new file mode 100644
index 0000000..3ecafe2
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <color name="menu_search_background">#ff676f74</color>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/config.xml b/packages/DocumentsUI/res/values-sw720dp/config.xml
new file mode 100644
index 0000000..4898e74
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Indicates if search view is taking the whole toolbar space -->
+    <bool name="full_bar_search_view">false</bool>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index b32c324..43543c6 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ஆவணத்திற்கு மறுபெயரிடுவதில் தோல்வி"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"சில கோப்புகள் மாற்றப்பட்டன"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> இல் உள்ள <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> இல் உள்ள படங்கள், வீடியோக்கள் உட்பட எல்லா தரவையும் அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"மீண்டும் கேட்காதே"</string>
     <string name="allow" msgid="7225948811296386551">"அனுமதி"</string>
     <string name="deny" msgid="2081879885755434506">"நிராகரி"</string>
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index e77fd66..47d2c48 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"పత్రం పేరు మార్చడంలో విఫలమైంది"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"కొన్ని పైల్‌లు మార్చబడ్డాయి"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="STORAGE"><i>^3</i></xliff:g>లో <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>లో ఫోటోలు మరియు వీడియోలతో సహా మీ డేటా ప్రాప్యతను <xliff:g id="APPNAME"><b>^1</b></xliff:g>కి మంజూరు చేయాలా?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"మళ్లీ అడగవద్దు"</string>
     <string name="allow" msgid="7225948811296386551">"అనుమతించండి"</string>
     <string name="deny" msgid="2081879885755434506">"తిరస్కరించండి"</string>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index 4d94795..99009b4 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"ไม่สามารถเปลี่ยนชื่อเอกสาร"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"แปลงบางไฟล์แล้ว"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ในการเข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ใน <xliff:g id="STORAGE"><i>^3</i></xliff:g> ไหม"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงข้อมูลของคุณ รวมถึงรูปภาพและวิดีโอใน <xliff:g id="STORAGE"><i>^2</i></xliff:g> ไหม"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"ไม่ต้องถามอีก"</string>
     <string name="allow" msgid="7225948811296386551">"อนุญาต"</string>
     <string name="deny" msgid="2081879885755434506">"ปฏิเสธ"</string>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index f395a5b..dd08e13 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Hindi napalitan ang pangalan ng dokumento"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Na-convert ang ilang file"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa directory ng <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa iyong data, kabilang ang mga larawan at video, sa <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Huwag nang tatanunging muli"</string>
     <string name="allow" msgid="7225948811296386551">"Payagan"</string>
     <string name="deny" msgid="2081879885755434506">"Tanggihan"</string>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index bc4db0d..3cc53e1 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Dokümanın adı değiştirilemedi"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bazı dosyalar dönüştürüldü"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına <xliff:g id="STORAGE"><i>^3</i></xliff:g> depolama alanındaki <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişim izni verilsin mi?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasının, fotoğraflar ve videolar dahil olmak üzere <xliff:g id="STORAGE"><i>^2</i></xliff:g> üzerindeki verilerinize erişmesine izin verilsin mi?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Tekrar sorma"</string>
     <string name="allow" msgid="7225948811296386551">"İzin Ver"</string>
     <string name="deny" msgid="2081879885755434506">"Reddet"</string>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index 79b6fbf..f9620a0 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -125,6 +125,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Не вдалося перейменувати документ"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Деякі файли конвертовано"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на пристрої пам’яті <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до ваших даних, зокрема до фотографій і відео, які містить <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Не запитувати знову"</string>
     <string name="allow" msgid="7225948811296386551">"Дозвол."</string>
     <string name="deny" msgid="2081879885755434506">"Забор."</string>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 4498f87..76d4cee 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"دستاویز کا نام تبدیل کرنے میں ناکام"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"کچھ فائلوں کو تبدیل کیا گیا تھا"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="STORAGE"><i>^3</i></xliff:g> پر <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی عطا کریں؟"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو اپنے ڈیٹا بشمول <xliff:g id="STORAGE"><i>^2</i></xliff:g> پر موجود تصاویر اور ویڈیوز تک رسائی عطا کریں؟"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"دوبارہ نہ پوچھیں"</string>
     <string name="allow" msgid="7225948811296386551">"اجازت دیں"</string>
     <string name="deny" msgid="2081879885755434506">"مسترد کریں"</string>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index b4f435b..47f1ac1 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Hujjatni qayta nomlab bo‘lmadi"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bir nechta fayllar o‘girildi"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasining <xliff:g id="STORAGE"><i>^3</i></xliff:g> xotirasidagi “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildiga kirishiga ruxsat berilsinmi?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasining <xliff:g id="STORAGE"><i>^2</i></xliff:g> xotirasidagi ma’lumotlardan, jumladan, rasmlar va videolardan foydalanishiga ruxsat berilsinmi?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Boshqa so‘ralmasin"</string>
     <string name="allow" msgid="7225948811296386551">"Ruxsat berish"</string>
     <string name="deny" msgid="2081879885755434506">"Rad qilish"</string>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index b64026a..613f271 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Không đổi được tên tài liệu"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Đã chuyển đổi một số tệp"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> trong <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào dữ liệu của bạn, kể cả ảnh và video trên <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Không hỏi lại"</string>
     <string name="allow" msgid="7225948811296386551">"Cho phép"</string>
     <string name="deny" msgid="2081879885755434506">"Từ chối"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index 90d1619..3bfeaaf 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"无法重命名文档"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分文件已转换成其他格式"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的“<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>”目录吗?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问您 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的数据(包括照片和视频)吗?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"不再询问"</string>
     <string name="allow" msgid="7225948811296386551">"允许"</string>
     <string name="deny" msgid="2081879885755434506">"拒绝"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index aeda260..7587086 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄存取權嗎?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要向「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的相片和影片等資料的存取權嗎?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string>
     <string name="allow" msgid="7225948811296386551">"允許"</string>
     <string name="deny" msgid="2081879885755434506">"拒絕"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index dc76411..7f13098 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要允許「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」存取 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的資料 (包括相片和影片) 嗎?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string>
     <string name="allow" msgid="7225948811296386551">"允許"</string>
     <string name="deny" msgid="2081879885755434506">"拒絕"</string>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index c53031b..6453059 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -111,6 +111,7 @@
     <string name="rename_error" msgid="4203041674883412606">"Yehlulekile ukuqamba kabusha idokhumenti"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Amanye amafayela aguqulelwe"</string>
     <string name="open_external_dialog_request" msgid="5789329484285817629">"Nika i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela ekuqondiseni kwe-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ku-<xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+    <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Nikeza i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela kudatha yakho, okufaka izithombe namavidiyo, ku-<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
     <string name="never_ask_again" msgid="4295278542972859268">"Ungaphindi ubuze"</string>
     <string name="allow" msgid="7225948811296386551">"Vumela"</string>
     <string name="deny" msgid="2081879885755434506">"Yala"</string>
diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml
index 04b7fee..1660e26 100644
--- a/packages/DocumentsUI/res/values/colors.xml
+++ b/packages/DocumentsUI/res/values/colors.xml
@@ -16,6 +16,7 @@
 
 <resources>
     <color name="material_grey_400">#ffbdbdbd</color>
+    <color name="material_teal_700">#ff00796b</color>
 
     <!-- This is the window background, but also the background for anything
          else that needs to manually declare a background matching the "default"
@@ -23,7 +24,7 @@
     <color name="window_background">#fff1f1f1</color>
     <color name="drawer_background">#fff1f1f1</color>
     <color name="directory_background">#fff7f7f7</color>
-    <color name="menu_search_background">#ff676f74</color>
+    <color name="menu_search_background">@android:color/transparent</color>
 
     <color name="primary_dark">@*android:color/primary_dark_material_dark</color>
     <color name="primary">@*android:color/material_blue_grey_900</color>
@@ -36,6 +37,8 @@
 
     <color name="item_doc_background_disabled">#fff4f4f4</color>
 
+    <color name="root_activated_color">@color/material_teal_700</color>
+
     <!-- TODO: Would be nice to move this to a color-set, but not sure how to support animation -->
     <color name="item_doc_background">#fffafafa</color>
     <color name="item_doc_background_selected">#ffe0f2f1</color>
diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml
index 408603e..765211d 100644
--- a/packages/DocumentsUI/res/values/config.xml
+++ b/packages/DocumentsUI/res/values/config.xml
@@ -26,4 +26,6 @@
     <bool name="home_root_hidden">true</bool>
     <!-- Indicates if the advanced roots like internal storage should be hidden in the roots list) -->
     <bool name="advanced_roots_hidden">true</bool>
+    <!-- Indicates if search view is taking the whole toolbar space -->
+    <bool name="full_bar_search_view">true</bool>
 </resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index a548d89..b16554c 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -36,6 +36,8 @@
         <item name="android:windowActionBar">false</item>
         <item name="android:windowActionModeOverlay">true</item>
         <item name="android:windowNoTitle">true</item>
+        <item name="android:windowTranslucentStatus">true</item>
+        <item name="android:fitsSystemWindows">false</item>
 
         <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
     </style>
@@ -43,7 +45,7 @@
     <style name="TrimmedHorizontalProgressBar" parent="android:Widget.Material.ProgressBar.Horizontal">
         <item name="android:indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material_trimmed</item>
         <item name="android:minHeight">3dp</item>
-        <item name="android:maxHeight">3dp</item>    
+        <item name="android:maxHeight">3dp</item>
     </style>
 
 </resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 2911027..69315f7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -58,6 +58,7 @@
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.Executor;
 
@@ -79,6 +80,7 @@
     private int mLayoutId;
 
     private boolean mNavDrawerHasFocus;
+    private long mStartTime;
 
     public abstract void onDocumentPicked(DocumentInfo doc, Model model);
     public abstract void onDocumentsPicked(List<DocumentInfo> docs);
@@ -96,16 +98,14 @@
     @CallSuper
     @Override
     public void onCreate(Bundle icicle) {
+        // Record the time when onCreate is invoked for metric.
+        mStartTime = new Date().getTime();
+
         super.onCreate(icicle);
 
         final Intent intent = getIntent();
 
-        // If startup benchmark is requested by a whitelisted testing package, then close the
-        // activity once idle, and notify the testing activity.
-        if (intent.getBooleanExtra(EXTRA_BENCHMARK, false) &&
-                BENCHMARK_TESTING_PACKAGE.equals(getCallingPackage())) {
-            closeOnIdleForTesting();
-        }
+        addListenerForLaunchCompletion();
 
         setContentView(mLayoutId);
 
@@ -127,6 +127,7 @@
         mSearchManager = new SearchViewManager(this, icicle);
 
         DocumentsToolbar toolbar = (DocumentsToolbar) findViewById(R.id.toolbar);
+        Display.adjustToolbar(toolbar, this);
         setActionBar(toolbar);
         mNavigator = new NavigationView(
                 mDrawer,
@@ -145,7 +146,8 @@
 
         getMenuInflater().inflate(R.menu.activity, menu);
         mNavigator.update();
-        mSearchManager.install((DocumentsToolbar) findViewById(R.id.toolbar));
+        boolean fullBarSearch = getResources().getBoolean(R.bool.full_bar_search_view);
+        mSearchManager.install((DocumentsToolbar) findViewById(R.id.toolbar), fullBarSearch);
 
         return showMenu;
     }
@@ -377,8 +379,12 @@
     public void onSearchChanged(@Nullable String query) {
         // We should not get here if root is not searchable
         assert(canSearchRoot());
-
         reloadSearch(query);
+    }
+
+    @Override
+    public void onSearchFinished() {
+        // Restores menu icons state
         invalidateOptionsMenu();
     }
 
@@ -604,12 +610,10 @@
         return super.onKeyDown(keyCode, event);
     }
 
-    @VisibleForTesting
     public void addEventListener(EventListener listener) {
         mEventListeners.add(listener);
     }
 
-    @VisibleForTesting
     public void removeEventListener(EventListener listener) {
         mEventListeners.remove(listener);
     }
@@ -673,6 +677,44 @@
         return false;
     }
 
+    /**
+     * Closes the activity when it's idle.
+     */
+    private void addListenerForLaunchCompletion() {
+        addEventListener(new EventListener() {
+            @Override
+            public void onDirectoryNavigated(Uri uri) {
+            }
+
+            @Override
+            public void onDirectoryLoaded(Uri uri) {
+                removeEventListener(this);
+                getMainLooper().getQueue().addIdleHandler(new IdleHandler() {
+                    @Override
+                    public boolean queueIdle() {
+                        // If startup benchmark is requested by a whitelisted testing package, then
+                        // close the activity once idle, and notify the testing activity.
+                        if (getIntent().getBooleanExtra(EXTRA_BENCHMARK, false) &&
+                                BENCHMARK_TESTING_PACKAGE.equals(getCallingPackage())) {
+                            setResult(RESULT_OK);
+                            finish();
+                        }
+
+                        Metrics.logStartupMs(
+                                BaseActivity.this, (int) (new Date().getTime() - mStartTime));
+
+                        // Remove the idle handler.
+                        return false;
+                    }
+                });
+                new Handler().post(new Runnable() {
+                    @Override public void run() {
+                    }
+                });
+            }
+        });
+    }
+
     private static final class PickRootTask extends PairedTask<BaseActivity, Void, DocumentInfo> {
         private RootInfo mRoot;
 
@@ -694,33 +736,6 @@
         }
     }
 
-    /**
-     * Closes the activity when it's idle. Used only for tests.
-     */
-    private void closeOnIdleForTesting() {
-        addEventListener(new EventListener() {
-            @Override
-            public void onDirectoryNavigated(Uri uri) {
-            }
-
-            @Override
-            public void onDirectoryLoaded(Uri uri) {
-                getMainLooper().getQueue().addIdleHandler(new IdleHandler() {
-                    @Override
-                    public boolean queueIdle() {
-                        setResult(RESULT_OK);
-                        finish();
-                        return false;
-                    }
-                });
-                new Handler().post(new Runnable() {
-                    @Override public void run() {
-                    }
-                });
-            }
-        });
-    }
-
     private static final class HandleRootsChangedTask
             extends PairedTask<BaseActivity, RootInfo, RootInfo> {
         DocumentInfo mDownloadsDocument;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Display.java b/packages/DocumentsUI/src/com/android/documentsui/Display.java
index bae2d58..d46a3ea 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Display.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Display.java
@@ -20,13 +20,15 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.util.TypedValue;
+import android.view.WindowManager;
+import android.widget.Toolbar;
 
 /*
  * Convenience class for getting display related attributes
  */
 public final class Display {
     /*
-     * Returns the screen width in pixels.
+     * Returns the screen width in raw pixels.
      */
     public static float screenWidth(Activity activity) {
         Point size = new Point();
@@ -42,15 +44,44 @@
     }
 
     /*
-     * Returns action bar height in pixels.
+     * Returns action bar height in raw pixels.
      */
     public static float actionBarHeight(Context context) {
-        int actionBarHeight = 0;
+        int height = 0;
         TypedValue tv = new TypedValue();
         if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
-            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,
+            height = TypedValue.complexToDimensionPixelSize(tv.data,
                     context.getResources().getDisplayMetrics());
         }
-        return actionBarHeight;
+        return height;
+    }
+
+    /*
+     * Returns status bar height in raw pixels.
+     */
+    private static int statusBarHeight(Context context) {
+        int height = 0;
+        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen",
+                "android");
+        if (resourceId > 0) {
+            height = context.getResources().getDimensionPixelSize(resourceId);
+        }
+        return height;
+    }
+
+    /*
+     * Adjusts toolbar for the layout with translucent status bar. Increases the
+     * height of the toolbar and adds padding at the top to accommodate status bar visible above
+     * toolbar.
+     */
+    public static void adjustToolbar(Toolbar toolbar, Activity activity) {
+        if ((activity.getWindow().getAttributes().flags
+                & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) != 0) {
+            int statusBarHeight = Display.statusBarHeight(activity);
+            toolbar.getLayoutParams().height = (int) (Display.actionBarHeight(activity)
+                    + statusBarHeight);
+            toolbar.setPadding(toolbar.getPaddingLeft(), statusBarHeight, toolbar.getPaddingRight(),
+                    toolbar.getPaddingBottom());
+        }
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
index 020f2c0..2dbb730 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
@@ -55,7 +55,7 @@
 
         View drawer = activity.findViewById(R.id.drawer_roots);
         Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
-
+        Display.adjustToolbar(toolbar, activity);
         drawer.getLayoutParams().width = calculateDrawerWidth(activity);
 
         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 2af6c46..3e04e2a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -201,6 +201,8 @@
         newWindow.setVisible(true);
 
         Menus.disableHiddenItems(menu, pasteFromCb);
+        // It hides icon if searching in progress
+        mSearchManager.updateMenu();
         return true;
     }
 
@@ -381,7 +383,7 @@
             }
 
             // Open the Close drawer if it is closed and we're at the top of a root.
-            if (size == 1) {
+            if (size <= 1) {
                 mDrawer.setOpen(true);
                 // Remember so we don't just close it again if back is pressed again.
                 mDrawerLastFiddled = System.currentTimeMillis();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index 929d1e0..e6b22e6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -64,6 +64,7 @@
     private static final String COUNT_FILEOP_SYSTEM = "docsui_fileop_system";
     private static final String COUNT_FILEOP_EXTERNAL = "docsui_fileop_external";
     private static final String COUNT_FILEOP_CANCELED = "docsui_fileop_canceled";
+    private static final String COUNT_STARTUP_MS = "docsui_startup_ms";
 
     // Indices for bucketing roots in the roots histogram. "Other" is the catch-all index for any
     // root that is not explicitly recognized by the Metrics code (see {@link
@@ -347,7 +348,7 @@
     }
 
     /**
-     * Log the cancellation of a file operation.  Call this when a Job is canceled.
+     * Logs the cancellation of a file operation.  Call this when a Job is canceled.
      * @param context
      * @param operationType
      */
@@ -355,6 +356,15 @@
         logHistogram(context, COUNT_FILEOP_CANCELED, toMetricsOpType(operationType));
     }
 
+    /**
+     * Logs startup time in milliseconds.
+     * @param context
+     * @param startupMs Startup time in milliseconds.
+     */
+    public static void logStartupMs(Context context, int startupMs) {
+        logHistogram(context, COUNT_STARTUP_MS, startupMs);
+    }
+
     private static void logInterProviderFileOps(
             Context context,
             String histogram,
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
index 4d0ba4b..11b8891 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
@@ -23,7 +23,9 @@
 import android.provider.DocumentsContract.Root;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.Menu;
 import android.view.MenuItem;
+import android.view.MenuItem.OnActionExpandListener;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnFocusChangeListener;
@@ -36,10 +38,12 @@
  * Manages searching UI behavior.
  */
 final class SearchViewManager implements
-        SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener {
+        SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener,
+        OnActionExpandListener {
 
     public interface SearchManagerListener {
         void onSearchChanged(@Nullable String query);
+        void onSearchFinished();
     }
 
     public static final String TAG = "SearchManger";
@@ -48,10 +52,11 @@
     private boolean mSearchExpanded;
     private String mCurrentSearch;
     private boolean mIgnoreNextClose;
+    private boolean mFullBar;
 
     private DocumentsToolbar mActionBar;
-    private MenuItem mMenu;
-    private SearchView mView;
+    private MenuItem mMenuItem;
+    private SearchView mSearchView;
 
     public SearchViewManager(SearchManagerListener listener, @Nullable Bundle savedState) {
         mListener = listener;
@@ -62,45 +67,61 @@
         mListener = listener;
     }
 
-    public void install(DocumentsToolbar actionBar) {
-        // assert(mActionBar == null);
-
+    public void install(DocumentsToolbar actionBar, boolean isFullBarSearch) {
         mActionBar = actionBar;
-        mMenu = actionBar.getSearchMenu();
-        mView = (SearchView) mMenu.getActionView();
+        mMenuItem = actionBar.getSearchMenu();
+        mSearchView = (SearchView) mMenuItem.getActionView();
 
-        mView.setOnQueryTextListener(this);
-        mView.setOnCloseListener(this);
-        mView.setOnSearchClickListener(this);
-        mView.setOnQueryTextFocusChangeListener(this);
+        mSearchView.setOnQueryTextListener(this);
+        mSearchView.setOnCloseListener(this);
+        mSearchView.setOnSearchClickListener(this);
+        mSearchView.setOnQueryTextFocusChangeListener(this);
+
+        mFullBar = isFullBarSearch;
+        if (mFullBar) {
+            mMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
+                    | MenuItem.SHOW_AS_ACTION_ALWAYS);
+            mMenuItem.setOnActionExpandListener(this);
+        }
 
         restoreSearch();
     }
 
     /**
+     * Used to hide menu icons, when the search is being restored. Needed because search restoration
+     * is done before onPrepareOptionsMenu(Menu menu) that is overriding the icons visibility.
+     */
+    public void updateMenu() {
+        if (isSearching() && mFullBar) {
+            Menu menu = mActionBar.getMenu();
+            menu.setGroupVisible(R.id.group_hide_when_searching, false);
+        }
+    }
+
+    /**
      * @param root Info about the current directory.
      */
     void update(RootInfo root) {
-        if (mMenu == null) {
+        if (mMenuItem == null) {
             if (DEBUG) Log.d(TAG, "update called before Search MenuItem installed.");
             return;
         }
 
         if (mCurrentSearch != null) {
-            mMenu.expandActionView();
+            mMenuItem.expandActionView();
 
-            mView.setIconified(false);
-            mView.clearFocus();
-            mView.setQuery(mCurrentSearch, false);
+            mSearchView.setIconified(false);
+            mSearchView.clearFocus();
+            mSearchView.setQuery(mCurrentSearch, false);
         } else {
-            mView.clearFocus();
-            if (!mView.isIconified()) {
+            mSearchView.clearFocus();
+            if (!mSearchView.isIconified()) {
                 mIgnoreNextClose = true;
-                mView.setIconified(true);
+                mSearchView.setIconified(true);
             }
 
-            if (mMenu.isActionViewExpanded()) {
-                mMenu.collapseActionView();
+            if (mMenuItem.isActionViewExpanded()) {
+                mMenuItem.collapseActionView();
             }
         }
 
@@ -109,7 +130,7 @@
     }
 
     void showMenu(boolean visible) {
-        if (mMenu == null) {
+        if (mMenuItem == null) {
             if (DEBUG) Log.d(TAG, "showMenu called before Search MenuItem installed.");
             return;
         }
@@ -118,7 +139,7 @@
             mCurrentSearch = null;
         }
 
-        mMenu.setVisible(visible);
+        mMenuItem.setVisible(visible);
     }
 
     /**
@@ -129,46 +150,46 @@
     boolean cancelSearch() {
         if (isExpanded() || isSearching()) {
             // If the query string is not empty search view won't get iconified
-            mView.setQuery("", false);
-            // Causes calling onClose(). onClose() is triggering directory content update.
-            mView.setIconified(true);
+            mSearchView.setQuery("", false);
+
+            if (mFullBar) {
+               onClose();
+            } else {
+                // Causes calling onClose(). onClose() is triggering directory content update.
+                mSearchView.setIconified(true);
+            }
             return true;
         }
         return false;
     }
 
+    /**
+     * Sets search view into the searching state. Used to restore state after device orientation
+     * change.
+     */
     private void restoreSearch() {
         if (isSearching()) {
+            if(mFullBar) {
+                mMenuItem.expandActionView();
+            } else {
+                mSearchView.setIconified(false);
+            }
             onSearchExpanded();
-            mView.setIconified(false);
-            mView.setQuery(mCurrentSearch, false);
-            mView.clearFocus();
+            mSearchView.setQuery(mCurrentSearch, false);
+            mSearchView.clearFocus();
         }
     }
 
     private void onSearchExpanded() {
         mSearchExpanded = true;
-    }
-
-    boolean isSearching() {
-        return mCurrentSearch != null;
-    }
-
-    boolean isExpanded() {
-        return mSearchExpanded;
+        if(mFullBar) {
+            Menu menu = mActionBar.getMenu();
+            menu.setGroupVisible(R.id.group_hide_when_searching, false);
+        }
     }
 
     /**
-     * Called when owning activity is saving state to be used to restore state during creation.
-     * @param state Bundle to save state too
-     */
-    public void onSaveInstanceState(Bundle state) {
-        state.putString(Shared.EXTRA_QUERY, mCurrentSearch);
-    }
-
-    /**
-     * Clears the search. Clears the SearchView background color. Triggers refreshing of the
-     * directory content.
+     * Clears the search. Triggers refreshing of the directory content.
      * @return True if the default behavior of clearing/dismissing SearchView should be overridden.
      *         False otherwise.
      */
@@ -187,13 +208,26 @@
                 mListener.onSearchChanged(mCurrentSearch);
             }
         }
+
+        if(mFullBar) {
+            mMenuItem.collapseActionView();
+        }
+        mListener.onSearchFinished();
+
         return false;
     }
 
     /**
-     * Sets mSearchExpanded. Called when search icon is clicked to start search. Used to detect when
-     * the view expanded instead of onMenuItemActionExpand, because SearchView has showAsAction set
-     * to always and onMenuItemAction* methods are not called.
+     * Called when owning activity is saving state to be used to restore state during creation.
+     * @param state Bundle to save state too
+     */
+    public void onSaveInstanceState(Bundle state) {
+        state.putString(Shared.EXTRA_QUERY, mCurrentSearch);
+    }
+
+    /**
+     * Sets mSearchExpanded. Called when search icon is clicked to start search for both search view
+     * modes.
      */
     @Override
     public void onClick(View v) {
@@ -203,19 +237,22 @@
     @Override
     public boolean onQueryTextSubmit(String query) {
         mCurrentSearch = query;
-        mView.clearFocus();
+        mSearchView.clearFocus();
         if (mListener != null) {
             mListener.onSearchChanged(mCurrentSearch);
         }
         return true;
     }
 
+    /**
+     * Used to detect and handle back button pressed event when search is expanded.
+     */
     @Override
     public void onFocusChange(View v, boolean hasFocus) {
         if (!hasFocus) {
             if (mCurrentSearch == null) {
-                mView.setIconified(true);
-            } else if (TextUtils.isEmpty(mView.getQuery())) {
+                mSearchView.setIconified(true);
+            } else if (TextUtils.isEmpty(mSearchView.getQuery())) {
                 cancelSearch();
             }
         }
@@ -226,8 +263,34 @@
         return false;
     }
 
+    @Override
+    public boolean onMenuItemActionCollapse(MenuItem item) {
+        Menu menu = mActionBar.getMenu();
+        menu.setGroupVisible(R.id.group_hide_when_searching, true);
+
+        // Handles case when search view is collapsed by using the arrow on the left of the bar
+        if (isExpanded() || isSearching()) {
+            cancelSearch();
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean onMenuItemActionExpand(MenuItem item) {
+        return true;
+    }
+
     String getCurrentSearch() {
         return mCurrentSearch;
     }
 
+    boolean isSearching() {
+        return mCurrentSearch != null;
+    }
+
+    boolean isExpanded() {
+        return mSearchExpanded;
+    }
+
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index b2fd9c4..4acf85ee 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -527,9 +527,13 @@
 
             // Re-enable TalkBack for the toolbars, as they are no longer covered by action mode.
             final Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
-            final Toolbar rootsToolbar = (Toolbar) getActivity().findViewById(R.id.roots_toolbar);
             toolbar.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
-            rootsToolbar.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+
+            // This toolbar is not present in the fixed_layout
+            final Toolbar rootsToolbar = (Toolbar) getActivity().findViewById(R.id.roots_toolbar);
+            if (rootsToolbar != null) {
+                rootsToolbar.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+            }
         }
 
         @Override
@@ -544,13 +548,16 @@
                 // Hide the toolbars if action mode is enabled, so TalkBack doesn't navigate to
                 // these controls when using linear navigation.
                 final Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
-                final Toolbar rootsToolbar = (Toolbar) getActivity().findViewById(
-                        R.id.roots_toolbar);
                 toolbar.setImportantForAccessibility(
                         View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
-                rootsToolbar.setImportantForAccessibility(
-                        View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
 
+                // This toolbar is not present in the fixed_layout
+                final Toolbar rootsToolbar = (Toolbar) getActivity().findViewById(
+                        R.id.roots_toolbar);
+                if (rootsToolbar != null) {
+                    rootsToolbar.setImportantForAccessibility(
+                            View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+                }
                 return true;
             }
 
@@ -1042,7 +1049,7 @@
         }
 
         // Can't copy folders to downloads, because we don't show folders there.
-        if (!root.isDownloads()) {
+        if (root.isDownloads()) {
             for (DocumentInfo docs : files) {
                 if (docs.isDirectory()) {
                     return false;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
index b53e165..748da00 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
@@ -158,11 +158,11 @@
     }
 
     /**
-     * Starts the service for a move operation.
+     * Starts the service for a delete operation.
      *
      * @param jobId A unique jobid for this job.
      *     Use {@link #createJobId} if you don't have one handy.
-     * @param srcDocs A list of src files to copy.
+     * @param srcDocs A list of src files to delete.
      * @param srcParent Parent of all the source documents.
      * @return Id of the job.
      */
@@ -184,7 +184,7 @@
      *
      * @param jobId A unique jobid for this job.
      *     Use {@link #createJobId} if you don't have one handy.
-     * @param srcDocs A list of src files to copy.
+     * @param srcDocs A list of src files for an operation.
      * @return Id of the job.
      */
     public static Intent createBaseIntent(
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
index 3536593..b816287 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
@@ -21,6 +21,7 @@
 import android.content.ContextWrapper;
 import android.database.Cursor;
 import android.database.MatrixCursor;
+import android.database.MergeCursor;
 import android.provider.DocumentsContract.Document;
 import android.test.AndroidTestCase;
 import android.test.mock.MockContentResolver;
@@ -117,21 +118,25 @@
 
     // Tests multiple authorities with clashing document IDs.
     public void testModelIdIsUnique() {
-        MatrixCursor cIn = new MatrixCursor(COLUMNS);
+        MatrixCursor cIn1 = new MatrixCursor(COLUMNS);
+        MatrixCursor cIn2 = new MatrixCursor(COLUMNS);
 
         // Make two sets of items with the same IDs, under different authorities.
         final String AUTHORITY0 = "auth0";
         final String AUTHORITY1 = "auth1";
+
         for (int i = 0; i < ITEM_COUNT; ++i) {
-            MatrixCursor.RowBuilder row0 = cIn.newRow();
+            MatrixCursor.RowBuilder row0 = cIn1.newRow();
             row0.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY0);
             row0.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
 
-            MatrixCursor.RowBuilder row1 = cIn.newRow();
+            MatrixCursor.RowBuilder row1 = cIn2.newRow();
             row1.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY1);
             row1.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
         }
 
+        Cursor cIn = new MergeCursor(new Cursor[] { cIn1, cIn2 });
+
         // Update the model, then make sure it contains all the expected items.
         DirectoryResult r = new DirectoryResult();
         r.cursor = cIn;
diff --git a/packages/Keyguard/res/values-ky-rKG/strings.xml b/packages/Keyguard/res/values-ky-rKG/strings.xml
index 5089512..098d5a2 100644
--- a/packages/Keyguard/res/values-ky-rKG/strings.xml
+++ b/packages/Keyguard/res/values-ky-rKG/strings.xml
@@ -108,7 +108,7 @@
     <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM-картанын PUK-кодун ачуу кыйрады!"</string>
     <string name="kg_pin_accepted" msgid="1448241673570020097">"Код кабыл алынды!"</string>
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Байланыш жок."</string>
-    <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"Киргизүү ыкмасын которуу"</string>
+    <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"Киргизүү ыкмасын өзгөртүү"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Учак режими"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Түзмөк кайра күйгүзүлгөндөн кийин графикалык ачкыч талап кылынат"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Түзмөк кайра күйгүзүлгөндөн кийин PIN код талап кылынат"</string>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index 81666fe..a73dcb6 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -108,7 +108,7 @@
     <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM卡PUK码操作失败!"</string>
     <string name="kg_pin_accepted" msgid="1448241673570020097">"代码正确!"</string>
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"无服务。"</string>
-    <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"输入法切换按钮。"</string>
+    <string name="accessibility_ime_switch_button" msgid="2829803408288433429">"切换输入法"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"飞行模式"</string>
     <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"重启设备后需要绘制解锁图案"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"重启设备后需要输入 PIN 码"</string>
diff --git a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
index 2b44d51..1d4ed1d 100644
--- a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
+++ b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
@@ -51,6 +51,7 @@
 static jclass app_fuse_class;
 static jmethodID app_fuse_get_file_size;
 static jmethodID app_fuse_read_object_bytes;
+static jmethodID app_fuse_write_object_bytes;
 static jfieldID app_fuse_buffer;
 
 // NOTE:
@@ -140,6 +141,9 @@
             case FUSE_READ:
                 invoke_handler(fd, req, &AppFuse::handle_fuse_read);
                 return true;
+            case FUSE_WRITE:
+                invoke_handler(fd, req, &AppFuse::handle_fuse_write);
+                return true;
             case FUSE_RELEASE:
                 invoke_handler(fd, req, &AppFuse::handle_fuse_release);
                 return true;
@@ -289,6 +293,29 @@
         return 0;
     }
 
+    int handle_fuse_write(const fuse_in_header& /* header */,
+                          const fuse_write_in* in,
+                          FuseResponse<fuse_write_out>* out) {
+        if (in->size > MAX_WRITE) {
+            return -EINVAL;
+        }
+        const std::map<uint32_t, uint64_t>::iterator it = handles_.find(in->fh);
+        if (it == handles_.end()) {
+            return -EBADF;
+        }
+        const uint64_t offset = in->offset;
+        const uint32_t size = in->size;
+        const void* const buffer = reinterpret_cast<const uint8_t*>(in) + sizeof(fuse_write_in);
+        uint32_t written_size;
+        const int result = write_object_bytes(it->second, offset, size, buffer, &written_size);
+        if (result < 0) {
+            return result;
+        }
+        out->prepare_buffer();
+        out->data()->size = written_size;
+        return 0;
+    }
+
     int handle_fuse_release(const fuse_in_header& /* header */,
                             const fuse_release_in* in,
                             FuseResponse<void>* /* out */) {
@@ -355,6 +382,27 @@
         return read_size;
     }
 
+    int write_object_bytes(int inode, uint64_t offset, uint32_t size, const void* buffer,
+                           uint32_t* written_size) {
+        ScopedLocalRef<jbyteArray> array(
+                env_,
+                static_cast<jbyteArray>(env_->GetObjectField(self_, app_fuse_buffer)));
+        {
+            ScopedByteArrayRW bytes(env_, array.get());
+            if (bytes.get() == nullptr) {
+                return -EIO;
+            }
+            memcpy(bytes.get(), buffer, size);
+        }
+        *written_size = env_->CallIntMethod(
+                self_, app_fuse_write_object_bytes, inode, offset, size, array.get());
+        if (env_->ExceptionCheck()) {
+            env_->ExceptionClear();
+            return -EIO;
+        }
+        return 0;
+    }
+
     static void fuse_reply(int fd, int unique, int reply_code, void* reply_data,
                            size_t reply_size) {
         // Don't send any data for error case.
@@ -469,6 +517,28 @@
         return -1;
     }
 
+    app_fuse_write_object_bytes = env->GetMethodID(app_fuse_class, "writeObjectBytes", "(IJI[B)I");
+    if (app_fuse_write_object_bytes == nullptr) {
+        ALOGE("Can't find getWriteObjectBytes");
+        return -1;
+    }
+
+    app_fuse_buffer = env->GetFieldID(app_fuse_class, "mBuffer", "[B");
+    if (app_fuse_buffer == nullptr) {
+        ALOGE("Can't find mBuffer");
+        return -1;
+    }
+
+    const jfieldID read_max_fied = env->GetStaticFieldID(app_fuse_class, "MAX_READ", "I");
+    if (static_cast<int>(env->GetStaticIntField(app_fuse_class, read_max_fied)) != MAX_READ) {
+        return -1;
+    }
+
+    const jfieldID write_max_fied = env->GetStaticFieldID(app_fuse_class, "MAX_WRITE", "I");
+    if (static_cast<int>(env->GetStaticIntField(app_fuse_class, write_max_fied)) != MAX_WRITE) {
+        return -1;
+    }
+
     const int result = android::AndroidRuntime::registerNativeMethods(
             env, "com/android/mtp/AppFuse", gMethods, NELEM(gMethods));
     if (result < 0) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
index 38435f4..777dc60 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
@@ -38,8 +38,12 @@
      * Max read amount specified at the FUSE kernel implementation.
      * The value is copied from sdcard.c.
      */
+    @UsedByNative("com_android_mtp_AppFuse.cpp")
     static final int MAX_READ = 128 * 1024;
 
+    @UsedByNative("com_android_mtp_AppFuse.cpp")
+    static final int MAX_WRITE = 256 * 1024;
+
     private final String mName;
     private final Callback mCallback;
 
@@ -47,7 +51,7 @@
      * Buffer for read bytes request.
      * Don't use the buffer from the out of AppFuseMessageThread.
      */
-    private byte[] mBuffer = new byte[MAX_READ];
+    private byte[] mBuffer = new byte[Math.max(MAX_READ, MAX_WRITE)];
 
     private Thread mMessageThread;
     private ParcelFileDescriptor mDeviceFd;
@@ -79,11 +83,22 @@
         }
     }
 
-    public ParcelFileDescriptor openFile(int i) throws FileNotFoundException {
+    /**
+     * Opens a file on app fuse and returns ParcelFileDescriptor.
+     *
+     * @param i ID for opened file.
+     * @param mode Mode for opening file.
+     * @see ParcelFileDescriptor#MODE_READ_ONLY
+     * @see ParcelFileDescriptor#MODE_WRITE_ONLY
+     */
+    public ParcelFileDescriptor openFile(int i, int mode) throws FileNotFoundException {
+        Preconditions.checkArgument(
+                mode == ParcelFileDescriptor.MODE_READ_ONLY ||
+                mode == ParcelFileDescriptor.MODE_WRITE_ONLY);
         return ParcelFileDescriptor.open(new File(
                 getMountPoint(),
                 Integer.toString(i)),
-                ParcelFileDescriptor.MODE_READ_ONLY);
+                mode);
     }
 
     File getMountPoint() {
@@ -100,7 +115,7 @@
         long getFileSize(int inode) throws FileNotFoundException;
 
         /**
-         * Returns flie bytes for the give inode.
+         * Returns file bytes for the give inode.
          * @param inode
          * @param offset Offset for file bytes.
          * @param size Size for file bytes.
@@ -109,6 +124,17 @@
          * @throws IOException
          */
         long readObjectBytes(int inode, long offset, long size, byte[] bytes) throws IOException;
+
+        /**
+         * Handles writing bytes for the give inode.
+         * @param inode
+         * @param offset Offset for file bytes.
+         * @param size Size for file bytes.
+         * @param bytes Buffer to store file bytes.
+         * @return Number of read bytes. Must not be negative.
+         * @throws IOException
+         */
+        int writeObjectBytes(int inode, long offset, int size, byte[] bytes) throws IOException;
     }
 
     @UsedByNative("com_android_mtp_AppFuse.cpp")
@@ -118,6 +144,8 @@
             return mCallback.getFileSize(inode);
         } catch (FileNotFoundException e) {
             return -OsConstants.ENOENT;
+        } catch (UnsupportedOperationException e) {
+            return -OsConstants.ENOTSUP;
         }
     }
 
@@ -138,6 +166,15 @@
         }
     }
 
+    @UsedByNative("com_android_mtp_AppFuse.cpp")
+    @WorkerThread
+    private /* unsgined */ int writeObjectBytes(int inode,
+                                                /* unsigned */ long offset,
+                                                /* unsigned */ int size,
+                                                byte[] bytes) throws IOException {
+        return mCallback.writeObjectBytes(inode, offset, size, bytes);
+    }
+
     private native boolean native_start_app_fuse_loop(int fd);
 
     private class AppFuseMessageThread extends Thread {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index 68f426f..246b95de 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -20,6 +20,7 @@
 import android.annotation.WorkerThread;
 import android.content.ContentResolver;
 import android.database.Cursor;
+import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
 import android.net.Uri;
 import android.os.Bundle;
@@ -340,13 +341,46 @@
                     Log.e(MtpDocumentsProvider.TAG, "Failed to load object info", error);
                 }
             }
+            final long[] objectSizeList = new long[infoList.size()];
+            for (int i = 0; i < infoList.size(); i++) {
+                final MtpObjectInfo info = infoList.get(i);
+                // Compressed size is 32-bit unsigned integer but getCompressedSize returns the
+                // value in Java int (signed 32-bit integer). Use getCompressedSizeLong instead
+                // to get the value in Java long.
+                if (info.getCompressedSizeLong() != 0xffffffffl) {
+                    objectSizeList[i] = info.getCompressedSizeLong();
+                    continue;
+                }
+
+                if (!MtpDeviceRecord.isSupported(
+                        mOperationsSupported,
+                        MtpConstants.OPERATION_GET_OBJECT_PROP_DESC) ||
+                        !MtpDeviceRecord.isSupported(
+                                mOperationsSupported,
+                                MtpConstants.OPERATION_GET_OBJECT_PROP_VALUE)) {
+                    objectSizeList[i] = -1;
+                    continue;
+                }
+
+                // Object size is more than 4GB.
+                try {
+                    objectSizeList[i] = mManager.getObjectSizeLong(
+                            mIdentifier.mDeviceId,
+                            info.getObjectHandle(),
+                            info.getFormat());
+                } catch (IOException error) {
+                    Log.e(MtpDocumentsProvider.TAG, "Failed to get object size property.", error);
+                    objectSizeList[i] = -1;
+                }
+            }
             synchronized (this) {
                 try {
                     mDatabase.getMapper().putChildDocuments(
                             mIdentifier.mDeviceId,
                             mIdentifier.mDocumentId,
                             mOperationsSupported,
-                            infoList.toArray(new MtpObjectInfo[infoList.size()]));
+                            infoList.toArray(new MtpObjectInfo[infoList.size()]),
+                            objectSizeList);
                 } catch (FileNotFoundException error) {
                     // Looks like the parent document information is removed.
                     // Adding documents has already cancelled in Mapper so we don't need to invoke
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
index 8058183..adc71ae 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
@@ -128,16 +128,27 @@
      * @param deviceId Device ID
      * @param parentId Parent document ID.
      * @param documents List of document information.
+     * @param documentSizes 64-bit size of documents. MtpObjectInfo#getComporessedSize will be
+     *     ignored because it does not contain 4GB> object size. Can be -1 if the size is unknown.
      * @throws FileNotFoundException
      */
     synchronized void putChildDocuments(
-            int deviceId, String parentId, int[] operationsSupported, MtpObjectInfo[] documents)
+            int deviceId, String parentId,
+            int[] operationsSupported,
+            MtpObjectInfo[] documents,
+            long[] documentSizes)
             throws FileNotFoundException {
+        assert documents.length == documentSizes.length;
         final ContentValues[] valuesList = new ContentValues[documents.length];
         for (int i = 0; i < documents.length; i++) {
             valuesList[i] = new ContentValues();
             MtpDatabase.getObjectDocumentValues(
-                    valuesList[i], deviceId, parentId, operationsSupported, documents[i]);
+                    valuesList[i],
+                    deviceId,
+                    parentId,
+                    operationsSupported,
+                    documents[i],
+                    documentSizes[i]);
         }
         putDocuments(
                 parentId,
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
index 4564018..cce619e 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
@@ -372,12 +372,16 @@
      * newly added and never mapped with existing ones.
      * @param parentDocumentId
      * @param info
+     * @param size Object size. info#getCompressedSize() will be ignored because it does not contain
+     *     object size more than 4GB.
      * @return Document ID of added document.
      */
     String putNewDocument(
-            int deviceId, String parentDocumentId, int[] operationsSupported, MtpObjectInfo info) {
+            int deviceId, String parentDocumentId, int[] operationsSupported, MtpObjectInfo info,
+            long size) {
         final ContentValues values = new ContentValues();
-        getObjectDocumentValues(values, deviceId, parentDocumentId, operationsSupported, info);
+        getObjectDocumentValues(
+                values, deviceId, parentDocumentId, operationsSupported, info, size);
         mDatabase.beginTransaction();
         try {
             final long id = mDatabase.insert(TABLE_DOCUMENTS, null, values);
@@ -586,9 +590,9 @@
     }
 
     void updateObject(String documentId, int deviceId, String parentId, int[] operationsSupported,
-                      MtpObjectInfo info) {
+                      MtpObjectInfo info, Long size) {
         final ContentValues values = new ContentValues();
-        getObjectDocumentValues(values, deviceId, parentId, operationsSupported, info);
+        getObjectDocumentValues(values, deviceId, parentId, operationsSupported, info, size);
 
         mDatabase.beginTransaction();
         try {
@@ -811,11 +815,12 @@
      * @param values {@link ContentValues} that receives values.
      * @param deviceId Device ID of the object.
      * @param parentId Parent document ID of the object.
-     * @param info MTP object info.
+     * @param info MTP object info. getCompressedSize will be ignored.
+     * @param size 64-bit size of documents. Negative value is regarded as unknown size.
      */
     static void getObjectDocumentValues(
             ContentValues values, int deviceId, String parentId,
-            int[] operationsSupported, MtpObjectInfo info) {
+            int[] operationsSupported, MtpObjectInfo info, long size) {
         values.clear();
         final String mimeType = getMimeType(info);
         values.put(COLUMN_DEVICE_ID, deviceId);
@@ -834,7 +839,11 @@
         values.put(Document.COLUMN_FLAGS, getDocumentFlags(
                 operationsSupported, mimeType, info.getThumbCompressedSizeLong(),
                 info.getProtectionStatus(), DOCUMENT_TYPE_OBJECT));
-        values.put(Document.COLUMN_SIZE, info.getCompressedSizeLong());
+        if (size >= 0) {
+            values.put(Document.COLUMN_SIZE, size);
+        } else {
+            values.putNull(Document.COLUMN_SIZE);
+        }
     }
 
     private static String getMimeType(MtpObjectInfo info) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
index 393c4de..c52b81d 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
@@ -56,8 +56,15 @@
     }
 
     static boolean isPartialReadSupported(@Nullable int[] supportedList, long fileSize) {
-        return fileSize <= 0xffffffffl &&
-                 isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT);
+        if (isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT_64)) {
+            return true;
+        }
+        if (0 <= fileSize &&
+                fileSize <= 0xffffffffL &&
+                isSupported(supportedList, MtpConstants.OPERATION_GET_PARTIAL_OBJECT)) {
+            return true;
+        }
+        return false;
     }
 
     static boolean isWritingSupported(@Nullable int[] supportedList) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index cf5bee5..9f64046ce 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -30,7 +30,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.CancellationSignal;
-import android.os.FileUriExposedException;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.os.storage.StorageManager;
@@ -235,14 +234,18 @@
             final MtpDeviceRecord device = getDeviceToolkit(identifier.mDeviceId).mDeviceRecord;
             switch (mode) {
                 case "r":
-                    final long fileSize = getFileSize(documentId);
+                    long fileSize;
+                    try {
+                        fileSize = getFileSize(documentId);
+                    } catch (UnsupportedOperationException exception) {
+                        fileSize = -1;
+                    }
                     // MTP getPartialObject operation does not support files that are larger than
                     // 4GB. Fallback to non-seekable file descriptor.
-                    // TODO: Use getPartialObject64 for MTP devices that support Android vendor
-                    // extension.
                     if (MtpDeviceRecord.isPartialReadSupported(
                             device.operationsSupported, fileSize)) {
-                        return mAppFuse.openFile(Integer.parseInt(documentId));
+                        return mAppFuse.openFile(
+                                Integer.parseInt(documentId), ParcelFileDescriptor.MODE_READ_ONLY);
                     } else {
                         return getPipeManager(identifier).readDocument(mMtpManager, identifier);
                     }
@@ -388,7 +391,7 @@
                     new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build();
             final String documentId = mDatabase.putNewDocument(
                     parentId.mDeviceId, parentDocumentId, record.operationsSupported,
-                    infoWithHandle);
+                    infoWithHandle, 0l);
             getDocumentLoader(parentId).clearTask(parentId);
             notifyChildDocumentsChange(parentDocumentId);
             return documentId;
@@ -543,6 +546,9 @@
                 MtpDatabase.strings(Document.COLUMN_SIZE, Document.COLUMN_DISPLAY_NAME));
         try {
             if (cursor.moveToNext()) {
+                if (cursor.isNull(0)) {
+                    throw new UnsupportedOperationException();
+                }
                 return cursor.getLong(0);
             } else {
                 throw new FileNotFoundException();
@@ -594,17 +600,32 @@
                 int inode, long offset, long size, byte[] buffer) throws IOException {
             final Identifier identifier = mDatabase.createIdentifier(Integer.toString(inode));
             final MtpDeviceRecord record = getDeviceToolkit(identifier.mDeviceId).mDeviceRecord;
-            if (MtpDeviceRecord.isPartialReadSupported(record.operationsSupported, offset)) {
+
+            if (MtpDeviceRecord.isSupported(
+                    record.operationsSupported, MtpConstants.OPERATION_GET_PARTIAL_OBJECT_64)) {
+                return mMtpManager.getPartialObject64(
+                        identifier.mDeviceId, identifier.mObjectHandle, offset, size, buffer);
+            }
+
+            if (0 <= offset && offset <= 0xffffffffL && MtpDeviceRecord.isSupported(
+                    record.operationsSupported, MtpConstants.OPERATION_GET_PARTIAL_OBJECT)) {
                 return mMtpManager.getPartialObject(
                         identifier.mDeviceId, identifier.mObjectHandle, offset, size, buffer);
-            } else {
-                throw new UnsupportedOperationException();
             }
+
+            throw new UnsupportedOperationException();
         }
 
         @Override
         public long getFileSize(int inode) throws FileNotFoundException {
             return MtpDocumentsProvider.this.getFileSize(String.valueOf(inode));
         }
+
+        @Override
+        public int writeObjectBytes(int inode, long offset, int size, byte[] bytes)
+                throws IOException {
+            // TODO: Implement it.
+            throw new IOException();
+        }
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 0599b70..00d31a71a 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -170,6 +170,14 @@
         }
     }
 
+    long getPartialObject64(int deviceId, int objectHandle, long offset, long size, byte[] buffer)
+            throws IOException {
+        final MtpDevice device = getDevice(deviceId);
+        synchronized (device) {
+            return device.getPartialObject64(objectHandle, offset, size, buffer);
+        }
+    }
+
     byte[] getThumbnail(int deviceId, int objectHandle) throws IOException {
         final MtpDevice device = getDevice(deviceId);
         synchronized (device) {
@@ -229,6 +237,11 @@
         return device.readEvent(signal);
     }
 
+    long getObjectSizeLong(int deviceId, int objectHandle, int format) throws IOException {
+        final MtpDevice device = getDevice(deviceId);
+        return device.getObjectSizeLong(objectHandle, format);
+    }
+
     private synchronized MtpDevice getDevice(int deviceId) throws IOException {
         final MtpDevice device = mDevices.get(deviceId);
         if (device == null) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
index c10a65e..1520f3b 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/PipeManager.java
@@ -174,7 +174,8 @@
                         mIdentifier.mDeviceId,
                         parentIdentifier.mDocumentId,
                         mOperationsSupported,
-                        newObjectInfo);
+                        newObjectInfo,
+                        tempFile.length());
             } catch (IOException error) {
                 Log.w(MtpDocumentsProvider.TAG,
                         "Failed to send a file because of: " + error.getMessage());
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/annotations/UsedByNative.java b/packages/MtpDocumentsProvider/src/com/android/mtp/annotations/UsedByNative.java
index a7f295f..2ded925 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/annotations/UsedByNative.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/annotations/UsedByNative.java
@@ -22,7 +22,7 @@
 /**
  * Annotation that shows the method is used by JNI.
  */
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.FIELD})
 public @interface UsedByNative {
     /**
      * JNI file name that uses the method.
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
index c0973bd..3b92506 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
@@ -56,7 +56,8 @@
                     }
                 });
         appFuse.mount(storageManager);
-        final ParcelFileDescriptor fd = appFuse.openFile(INODE);
+        final ParcelFileDescriptor fd = appFuse.openFile(
+                INODE, ParcelFileDescriptor.MODE_READ_ONLY);
         fd.close();
         appFuse.close();
     }
@@ -67,11 +68,21 @@
         final AppFuse appFuse = new AppFuse("test", new TestCallback());
         appFuse.mount(storageManager);
         try {
-            appFuse.openFile(INODE);
+            appFuse.openFile(INODE, ParcelFileDescriptor.MODE_READ_ONLY);
             fail();
-        } catch (Throwable t) {
-            assertTrue(t instanceof FileNotFoundException);
-        }
+        } catch (FileNotFoundException exp) {}
+        appFuse.close();
+    }
+
+    public void testOpenFile_illegalMode() throws IOException {
+        final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
+        final int INODE = 10;
+        final AppFuse appFuse = new AppFuse("test", new TestCallback());
+        appFuse.mount(storageManager);
+        try {
+            appFuse.openFile(INODE, ParcelFileDescriptor.MODE_READ_WRITE);
+            fail();
+        } catch (IllegalArgumentException exp) {}
         appFuse.close();
     }
 
@@ -105,7 +116,8 @@
                     }
                 });
         appFuse.mount(storageManager);
-        final ParcelFileDescriptor fd = appFuse.openFile(fileInode);
+        final ParcelFileDescriptor fd = appFuse.openFile(
+                fileInode, ParcelFileDescriptor.MODE_READ_ONLY);
         try (final ParcelFileDescriptor.AutoCloseInputStream stream =
                 new ParcelFileDescriptor.AutoCloseInputStream(fd)) {
             final byte[] buffer = new byte[1024];
@@ -115,6 +127,71 @@
         appFuse.close();
     }
 
+    public void testWriteFile() throws IOException {
+        final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
+        final int INODE = 10;
+        final byte[] resultBytes = new byte[5];
+        final AppFuse appFuse = new AppFuse(
+                "test",
+                new TestCallback() {
+                    @Override
+                    public long getFileSize(int inode) throws FileNotFoundException {
+                        if (inode != INODE) {
+                            throw new FileNotFoundException();
+                        }
+                        return resultBytes.length;
+                    }
+
+                    @Override
+                    public int writeObjectBytes(int inode, long offset, int size, byte[] bytes) {
+                        for (int i = 0; i < size; i++) {
+                            resultBytes[(int)(offset + i)] = bytes[i];
+                        }
+                        return size;
+                    }
+                });
+        appFuse.mount(storageManager);
+        final ParcelFileDescriptor fd = appFuse.openFile(
+                INODE, ParcelFileDescriptor.MODE_WRITE_ONLY);
+        try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
+                new ParcelFileDescriptor.AutoCloseOutputStream(fd)) {
+            stream.write('a');
+            stream.write('b');
+            stream.write('c');
+            stream.write('d');
+            stream.write('e');
+        }
+        final byte[] BYTES = new byte[] { 'a', 'b', 'c', 'd', 'e' };
+        assertTrue(Arrays.equals(BYTES, resultBytes));
+        appFuse.close();
+    }
+
+    public void testWriteFile_writeError() throws IOException {
+        final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
+        final int INODE = 10;
+        final AppFuse appFuse = new AppFuse(
+                "test",
+                new TestCallback() {
+                    @Override
+                    public long getFileSize(int inode) throws FileNotFoundException {
+                        if (inode != INODE) {
+                            throw new FileNotFoundException();
+                        }
+                        return 5;
+                    }
+                });
+        appFuse.mount(storageManager);
+        final ParcelFileDescriptor fd = appFuse.openFile(
+                INODE, ParcelFileDescriptor.MODE_WRITE_ONLY);
+        try (final ParcelFileDescriptor.AutoCloseOutputStream stream =
+                new ParcelFileDescriptor.AutoCloseOutputStream(fd)) {
+            stream.write('a');
+            fail();
+        } catch (IOException e) {
+        }
+        appFuse.close();
+    }
+
     private static class TestCallback implements AppFuse.Callback {
         @Override
         public long getFileSize(int inode) throws FileNotFoundException {
@@ -126,5 +203,11 @@
                 throws IOException {
             throw new IOException();
         }
+
+        @Override
+        public int writeObjectBytes(int inode, long offset, int size, byte[] bytes)
+                throws IOException {
+            throw new IOException();
+        }
     }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index 284223b..404047b 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -200,7 +200,7 @@
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
-        });
+        }, new long[] { 1024L, 2L * 1024L * 1024L, 3L * 1024L * 1024L});
 
         final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "2");
         assertEquals(3, cursor.getCount());
@@ -273,7 +273,7 @@
         mDatabase.getMapper().startAddingDocuments("2");
         mDatabase.getMapper().putChildDocuments(0, "2", new int[0], new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         try (final Cursor cursor =
@@ -290,7 +290,7 @@
                 MtpConstants.OPERATION_SEND_OBJECT_INFO,
         }, new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         try (final Cursor cursor =
@@ -306,7 +306,7 @@
                 MtpConstants.OPERATION_DELETE_OBJECT
         }, new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024)
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         try (final Cursor cursor =
@@ -395,7 +395,7 @@
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "image.jpg", MtpConstants.FORMAT_EXIF_JPEG, 2 * 1024 * 1024),
                 createDocument(102, "music.mp3", MtpConstants.FORMAT_MP3, 3 * 1024 * 1024)
-        });
+        }, new long[] { 1024L, 2L * 1024L * 1024L, 3L * 1024L * 1024L});
         mDatabase.getMapper().clearMapping();
 
         addTestDevice();
@@ -412,7 +412,7 @@
         mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024),
-        });
+        }, new long[] { 1024L, 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         {
@@ -545,7 +545,7 @@
         mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
                 createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
-        });
+        }, new long[] { 0L, 0L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         // Put note.txt in each directory.
@@ -553,10 +553,10 @@
         mDatabase.getMapper().startAddingDocuments("4");
         mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L });
 
         // Clear mapping.
         mDatabase.getMapper().clearMapping();
@@ -568,7 +568,7 @@
         mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
                 createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
-        });
+        }, new long[] { 0L, 0L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         // Add note.txt in each directory again.
@@ -576,10 +576,10 @@
         mDatabase.getMapper().startAddingDocuments("4");
         mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().putChildDocuments(0, "4", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().stopAddingDocuments("3");
         mDatabase.getMapper().stopAddingDocuments("4");
 
@@ -860,7 +860,7 @@
         mDatabase.getMapper().startAddingDocuments("2");
         mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         assertEquals("2", mDatabase.getParentIdentifier("3").mDocumentId);
@@ -873,13 +873,13 @@
         mDatabase.getMapper().startAddingDocuments("2");
         mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024),
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         mDatabase.getMapper().startAddingDocuments("3");
         mDatabase.getMapper().putChildDocuments(0, "3", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L });
         mDatabase.getMapper().stopAddingDocuments("3");
 
         mDatabase.deleteDocument("3");
@@ -909,7 +909,8 @@
                 "3",
                 mDatabase.putNewDocument(
                         0, "2", OPERATIONS_SUPPORTED,
-                        createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024)));
+                        createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
+                        1024L));
 
         {
             final Cursor cursor =
@@ -928,7 +929,8 @@
         mDatabase.getMapper().startAddingDocuments("2");
         mDatabase.putNewDocument(
                 0, "2", OPERATIONS_SUPPORTED,
-                createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024));
+                createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
+                1024L);
         mDatabase.getMapper().stopAddingDocuments("2");
 
         {
@@ -1045,7 +1047,7 @@
         mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L, 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         // Disconnect the device.
@@ -1064,7 +1066,7 @@
         mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] {
                 createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024),
-        });
+        }, new long[] { 1024L, 1024L });
         mDatabase.getMapper().stopAddingDocuments("2");
 
         try (final Cursor cursor = mDatabase.queryChildDocuments(
@@ -1093,7 +1095,7 @@
             createDocument(102, "unknown.mp4", MtpConstants.FORMAT_MPEG, 1000),
             createDocument(103, "inconsistent.txt", MtpConstants.FORMAT_MPEG, 1000),
             createDocument(104, "noext", MtpConstants.FORMAT_UNDEFINED, 1000),
-        });
+        }, new long[] { 1000L, 1000L, 1000L, 1000L, 1000L });
         mDatabase.getMapper().stopAddingDocuments("2");
         try (final Cursor cursor = mDatabase.queryChildDocuments(
                 strings(COLUMN_DISPLAY_NAME,  COLUMN_MIME_TYPE),
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index da6af37..0de761cb 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -708,6 +708,33 @@
         } catch (UnsupportedOperationException exception) {}
     }
 
+    public void testObjectSizeLong() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
+        mMtpManager.setObjectSizeLong(0, 100, MtpConstants.FORMAT_EXIF_JPEG, 0x400000000L);
+        setupDocuments(
+                0,
+                0,
+                MtpManager.OBJECT_HANDLE_ROOT_CHILDREN,
+                "1",
+                new MtpObjectInfo[] {
+                        new MtpObjectInfo.Builder()
+                                .setObjectHandle(100)
+                                .setFormat(MtpConstants.FORMAT_EXIF_JPEG)
+                                .setName("image.jpg")
+                                .setCompressedSize(0xffffffffl)
+                                .build()
+                });
+
+        final Cursor cursor = mProvider.queryDocument("3", new String[] {
+                DocumentsContract.Document.COLUMN_SIZE
+        });
+        assertEquals(1, cursor.getCount());
+
+        cursor.moveToNext();
+        assertEquals(0x400000000L, cursor.getLong(0));
+    }
+
     private void setupProvider(int flag) {
         mDatabase = new MtpDatabase(getContext(), flag);
         mProvider = new MtpDocumentsProvider();
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
index a08d9ee..8611797 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/PipeManagerTest.java
@@ -75,7 +75,8 @@
         mDatabase.getMapper().startAddingDocuments("2");
         mDatabase.getMapper().putChildDocuments(
                 0, "2", TestUtil.OPERATIONS_SUPPORTED,
-                new MtpObjectInfo[] { info });
+                new MtpObjectInfo[] { info },
+                new long[] { 0L });
         mDatabase.getMapper().stopAddingDocuments("2");
         // Create a placeholder file which should be replaced by a real file later.
         mtpManager.setObjectInfo(0, info);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
index 5171bd2..9a81489 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -39,6 +39,7 @@
     private final Map<String, int[]> mObjectHandles = new HashMap<>();
     private final Map<String, byte[]> mThumbnailBytes = new HashMap<>();
     private final Map<String, byte[]> mImportFileBytes = new HashMap<>();
+    private final Map<String, Long> mObjectSizeLongs = new HashMap<>();
 
     TestMtpManager(Context context) {
         super(context);
@@ -68,6 +69,10 @@
         mThumbnailBytes.put(pack(deviceId, objectHandle), bytes);
     }
 
+    void setObjectSizeLong(int deviceId, int objectHandle, int format, long value) {
+        mObjectSizeLongs.put(pack(deviceId, objectHandle, format), value);
+    }
+
     @Override
     MtpDeviceRecord[] getDevices() {
         final MtpDeviceRecord[] result = new MtpDeviceRecord[mDevices.size()];
@@ -214,4 +219,14 @@
         }
         return i;
     }
+
+    @Override
+    long getObjectSizeLong(int deviceId, int objectHandle, int format) throws IOException {
+        final String key = pack(deviceId, objectHandle, format);
+        if (mObjectSizeLongs.containsKey(key)) {
+            return mObjectSizeLongs.get(key);
+        } else {
+            throw new IOException();
+        }
+    }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
index 5ceab01..8805d19 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestUtil.java
@@ -38,6 +38,8 @@
             MtpConstants.OPERATION_SEND_OBJECT,
             MtpConstants.OPERATION_SEND_OBJECT_INFO,
             MtpConstants.OPERATION_DELETE_OBJECT,
+            MtpConstants.OPERATION_GET_OBJECT_PROP_DESC,
+            MtpConstants.OPERATION_GET_OBJECT_PROP_VALUE
     };
 
     /**
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 2bcd851..ed6fdb7 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -57,7 +57,7 @@
 
         <activity
             android:name=".ui.PrintActivity"
-            android:configChanges="screenSize|smallestScreenSize|orientation"
+            android:configChanges="screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection"
             android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE"
             android:theme="@style/Theme.PrintActivity">
             <intent-filter>
diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml
index c8478f2..0224c6c 100644
--- a/packages/PrintSpooler/res/values-af/strings.xml
+++ b/packages/PrintSpooler/res/values-af/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Herbegin"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met drukker nie"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie beskikbaar nie"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gebruik <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Jou dokument kan dalk deur een of meer bedieners op pad na die drukker gaan."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Jammer, dit het nie gewerk nie. Probeer weer."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Herprobeer"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Hierdie drukker is nie op die oomblik beskikbaar nie."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Kan nie voorskou wys nie"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Berei tans voorskou voor …"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
index d4426cc..98255d4 100644
--- a/packages/PrintSpooler/res/values-am/strings.xml
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"እንደገና ጀምር"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ከአታሚ ጋር ምንም ግንኙነት የለም"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"አይታወቅም"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – አይገኝም"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ይጠቀሙ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ሰነድዎ ወደ አታሚው በሚሄድበት ወቅት በአንድ ወይም ከዚያ በላይ አገልጋዮች ውስጥ ሊያልፍ ይችላል።"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"ይቅርታ፣ ያ አልሰራም። እንደገና ይሞክሩ።"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"እንደገና ይሞክሩ"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"አታሚው አሁን አይገኝም።"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"ቅድመ ዕይታን ማሳየት አይቻልም"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"ቅድመ እይታን በማዘጋጀት ላይ…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml
index 2e1b6d0..5f0255c 100644
--- a/packages/PrintSpooler/res/values-ar/strings.xml
+++ b/packages/PrintSpooler/res/values-ar/strings.xml
@@ -84,7 +84,6 @@
     <string name="restart" msgid="2472034227037808749">"إعادة تشغيل"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"لا يوجد اتصال بالطابعة"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"غير معروف"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – غير متاحة"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"هل تريد استخدام <xliff:g id="SERVICE">%1$s</xliff:g>؟"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"من الممكن أن يمر المستند عبر خادم أو أكثر أثناء إرساله إلى الطابعة."</string>
   <string-array name="color_mode_labels">
@@ -104,5 +103,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"عذرًا، هذا لا يعمل. أعد المحاولة."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"إعادة المحاولة"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"الطابعة ليست متوفرة في الوقت الحالي."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"يتعذر عرض المعاينة."</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"جارٍ تحضير المعاينة…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-az-rAZ/strings.xml b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
index 5490b84..b5dfaf8 100644
--- a/packages/PrintSpooler/res/values-az-rAZ/strings.xml
+++ b/packages/PrintSpooler/res/values-az-rAZ/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Yenidən başlat"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printerə heç bir bağlantı yoxdur"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"naməlum"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>– əlçatmaz"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> xidmətindən istifadə edilsin?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Sənədiniz printerə qədər bir və ya daha çox server vasitəsilə keçə bilər."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Üzr istəyirik, alınmadı. Yenidən cəhd edin."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Yenidən yoxla"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Bu printer hazırda əlçatan deyil."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Önizləmə göstərilə bilmir"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Önizləməyə hazırlıq gedir..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 0574dae..2ac8002 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -81,7 +81,6 @@
     <string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze sa štampačem"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nedostupan"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li da koristite <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument može da prođe kroz jedan ili više servera na putu do štampača."</string>
   <string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Žao nam je, ovo nije uspelo. Pokušajte ponovo."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Pokušajte ponovo"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ovaj štampač trenutno nije dostupan."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Nije uspeo prikaz pregleda"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-be-rBY/strings.xml b/packages/PrintSpooler/res/values-be-rBY/strings.xml
index b581045..13d573e 100644
--- a/packages/PrintSpooler/res/values-be-rBY/strings.xml
+++ b/packages/PrintSpooler/res/values-be-rBY/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Перазапусціць"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Няма падлучэння да прынтара"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"невядома"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недаступна"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Выкарыстоўваць службу <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Ваш дакумент можа прайсці праз адзін ці больш сервераў перад тым, як будзе надрукаваны."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"На жаль, не атрымалася. Паспрабуйце яшчэ раз."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Паўтарыць спробу"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Гэты прынтар зараз недаступны."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Папярэдні прагляд немагчымы"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Падрыхтоўка папярэдняга прагляду..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml
index 88af8e4..73c51e9 100644
--- a/packages/PrintSpooler/res/values-bg/strings.xml
+++ b/packages/PrintSpooler/res/values-bg/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Рестартиране"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Няма връзка с принтера"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"няма данни"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – не е налице"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Да се използва ли „<xliff:g id="SERVICE">%1$s</xliff:g>“?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"По пътя към принтера документът ви може да премине през един или повече сървъри."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"За съжаление това не проработи. Опитайте отново."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Нов опит"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"В момента този принтер не е налице."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Визуализацията не може да се покаже"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Визуализацията се подготвя…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
index c61ef74..25b4660 100644
--- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml
+++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"পুনর্সূচনা"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"মুদ্রকে কোনো সংযোগ নেই"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"অজানা"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – অনুপলব্ধ"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ব্যবহার করবেন?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"আপনার দস্তাবেজ মুদ্রকে যাওয়ার সময় এক বা একাধিক সার্ভারের মাধ্যমে পাস হতে পারে।"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"দুঃখিত, এটি কাজ করেনি৷ আবার চেষ্টা করুন৷"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"পুনরায় চেষ্টা করুন"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"এই মূহুর্তে প্রিন্টার উপলব্ধ নয়।"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"পূর্বরূপ প্রদর্শন করা যাবে না"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"পূর্বরূপ প্রস্তুত করছে..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-bs-rBA/strings.xml b/packages/PrintSpooler/res/values-bs-rBA/strings.xml
index 7465c3c..9a17707 100644
--- a/packages/PrintSpooler/res/values-bs-rBA/strings.xml
+++ b/packages/PrintSpooler/res/values-bs-rBA/strings.xml
@@ -81,7 +81,6 @@
     <string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema konekcije sa štampačem"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nepoznat"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nedostupan"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Zaista želite koristiti uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Moguće je da dokument prije štampanja prođe kroz jedan ili više servera."</string>
   <string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Nažalost, nije uspjelo. Pokušajte ponovo."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Ponovi"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Štampač trenutno nije dostupan."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Pregled se ne može prikazati"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
index 482100a..a1df406 100644
--- a/packages/PrintSpooler/res/values-ca/strings.xml
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Reinicia"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No hi ha connexió amb la impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconegut"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vols fer servir <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"És possible que el document passi com a mínim per un servidor abans d\'imprimir-se."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"No ha funcionat. Torna-ho a provar."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Torna-ho a provar"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ara mateix, aquesta impressora no està disponible."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"La previsualització no es pot mostrar"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"S\'està preparant la previsualització..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml
index a4c412c..55fb21b 100644
--- a/packages/PrintSpooler/res/values-cs/strings.xml
+++ b/packages/PrintSpooler/res/values-cs/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Restartovat"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nelze se připojit k tiskárně"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"neznámé"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – není k dispozici"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Použít službu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument může cestou do tiskárny projít jedním i více servery."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Litujeme, nepodařilo se. Zkuste to znovu."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Opakovat"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Tiskárna aktuálně není k dispozici."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Náhled nelze zobrazit"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Příprava náhledu…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml
index 9ee252167..49417bd 100644
--- a/packages/PrintSpooler/res/values-da/strings.xml
+++ b/packages/PrintSpooler/res/values-da/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Genstart"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse til printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ukendt"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ikke tilgængelig"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vil du bruge <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dit dokument passerer muligvis gennem én eller flere servere på vej til printeren."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Det virkede desværre ikke. Prøv igen."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Prøv igen"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Denne printer er i øjeblikket ikke tilgængelig."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Eksempelvisning kan ikke vises"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Eksempelvisning forberedes..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
index ef451b7..cb7aeee 100644
--- a/packages/PrintSpooler/res/values-de/strings.xml
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Neu starten"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Keine Verbindung zum Drucker"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unbekannt"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nicht verfügbar"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> verwenden?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dein Dokument passiert bei der Übermittlung an den Drucker möglicherweise einen oder mehrere Server."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Fehler. Bitte versuche es erneut."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Erneut versuchen"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Dieser Drucker ist momentan nicht verfügbar."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Vorschau kann nicht angezeigt werden"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Vorschau wird vorbereitet…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml
index 9be81c1..4441ea2 100644
--- a/packages/PrintSpooler/res/values-el/strings.xml
+++ b/packages/PrintSpooler/res/values-el/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Επανεκκίνηση"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Δεν υπάρχει σύνδεση με εκτυπωτή"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"άγνωστο"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – μη διαθέσιμο"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Να χρησιμοποιηθεί η υπηρεσία <xliff:g id="SERVICE">%1$s</xliff:g>;"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Το έγγραφό σας μπορεί να περάσει από έναν ή περισσότερους διακομιστές κατά τη μετάβαση στον εκτυπωτή."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Δυστυχώς, αυτό δεν λειτούργησε. Δοκιμάστε ξανά."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Επανάληψη"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Αυτός ο εκτυπωτής δεν είναι διαθέσιμος αυτήν τη στιγμή."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Αδυναμία προβολής προεπισκόπησης"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Προετοιμασία προεπισκόπησης…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml
index 8b58011..f8b6265 100644
--- a/packages/PrintSpooler/res/values-en-rAU/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Restart"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Can\'t display preview"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml
index 8b58011..f8b6265 100644
--- a/packages/PrintSpooler/res/values-en-rGB/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Restart"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Can\'t display preview"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml
index 8b58011..f8b6265 100644
--- a/packages/PrintSpooler/res/values-en-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Restart"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Use <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Your document may pass through one or more servers on its way to the printer."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Sorry, that didn\'t work. Try again."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Retry"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"This printer isn\'t available right now."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Can\'t display preview"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparing preview…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 8fa6094..8d55597 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora."</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"¿Deseas usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Es posible que el documento pase por uno o varios servidores antes de imprimirse."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"No funcionó. Vuelve a intentarlo."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Volver a intentar"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora no está disponible en este momento."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"No se puede mostrar la vista previa"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando vista previa…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
index dba0491..7d08a0e 100644
--- a/packages/PrintSpooler/res/values-es/strings.xml
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Volver a empezar"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – no disponible"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"¿Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Es posible que el documento pase por uno o varios servidores antes de imprimirse."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"No ha funcionado. Prueba de nuevo."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Reintentar"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora no está disponible en este momento."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"No se puede mostrar la vista previa"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando vista previa…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml
index 6dde083..09da3e0 100644
--- a/packages/PrintSpooler/res/values-et-rEE/strings.xml
+++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Taaskäivita"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printeriühendus puudub"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"teadmata"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – pole saadaval"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Kas soovite kasutada teenust <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Printerini jõudmiseks võib dokument läbida ühe või mitu serverit."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Kahjuks see ei toiminud. Proovige uuesti."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Proovi uuesti"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"See printer ei ole praegu saadaval."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Eelvaadet ei õnnestu kuvada"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Eelvaate ettevalmistamine ..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml
index 858444b..6b760b4 100644
--- a/packages/PrintSpooler/res/values-eu-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Berrabiarazi"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Inprimagailua ez dago konektatuta"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ezezaguna"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: ez dago erabilgarri"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> erabili nahi duzu?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Baliteke dokumentuak zerbitzari batean edo gehiagotan zehar igarotzea inprimagailurako bidean."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Horrek ez du funtzionatu. Saiatu berriro."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Saiatu berriro"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Une honetan inprimagailua ez dago erabilgarri."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Ezin da bistaratu aurrebista"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Aurrebista prestatzen…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
index 7c69c27..fa105d5 100644
--- a/packages/PrintSpooler/res/values-fa/strings.xml
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"راه‌اندازی مجدد"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"اتصال با چاپگر برقرار نیست"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"نامعلوم"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - در دسترس نیست"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"از <xliff:g id="SERVICE">%1$s</xliff:g> استفاده شود؟"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ممکن است سندتان برای رسیدن به چاپگر از یک یا چند سرور عبور کند."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"متأسفیم، تلاش ناموفق بود. دوباره امتحان کنید."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"امتحان مجدد"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"این چاپگر اکنون در دسترس نیست."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"نمایش پیش‌نمایش امکان‌پذیر نیست"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"در حال آماده‌سازی پیش‌نمایش…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml
index dfd98f8..cf051f8 100644
--- a/packages/PrintSpooler/res/values-fi/strings.xml
+++ b/packages/PrintSpooler/res/values-fi/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Käynnistä uudelleen"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ei yhteyttä tulostimeen"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"tuntematon"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ei käytettävissä"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Käytetäänkö palvelua <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Asiakirja saattaa kulkea yhden tai useamman palvelimen kautta matkalla tulostimeen."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Ei valitettavasti onnistunut. Yritä uudelleen."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Yritä uudelleen"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Tämä tulostin ei ole käyttävissä juuri nyt."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Esikatselua ei voi näyttää."</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Esikatselua valmistellaan…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index a95d565..11d2875 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Recommencer"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"inconnu"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — indisponible"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Utiliser <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Votre document peut passer par un ou plusieurs serveurs avant d\'arriver à l\'imprimante."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Échec de l\'action. Réessayez."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Réessayer"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Cette imprimante n\'est pas accessible pour le moment."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Impossible d\'afficher l\'aperçu"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Préparation de l\'aperçu en cours…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
index dd1f490..6b89281 100644
--- a/packages/PrintSpooler/res/values-fr/strings.xml
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Redémarrer"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante."</string>
     <string name="reason_unknown" msgid="5507940196503246139">"inconnue"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponible"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Utiliser <xliff:g id="SERVICE">%1$s</xliff:g> ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Votre document peut passer par un ou plusieurs serveurs avant d\'être envoyé sur l\'imprimante."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Échec de l\'opération. Veuillez réessayer."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Réessayer"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Cette imprimante n\'est pas disponible actuellement."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Impossible d\'afficher l\'aperçu"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Préparation de l\'aperçu en cours…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml
index 81e080e..7ddc9f8 100644
--- a/packages/PrintSpooler/res/values-gl-rES/strings.xml
+++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Non hai conexión coa impresora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"descoñecido"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: non dispoñible"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Queres usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"É posible que o teu documento pase por un ou máis servidores antes de imprimirse."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Non funcionou. Téntao de novo."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Tentar de novo"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora non está dispoñible nestes momentos."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Non se pode mostrar a vista previa"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando a vista previa…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-gu-rIN/strings.xml b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
index 44ede86..6a7e0df 100644
--- a/packages/PrintSpooler/res/values-gu-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-gu-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"પુનઃપ્રારંભ કરો"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"પ્રિન્ટર માટે કોઈ કનેક્શન નથી"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"અજાણ્યું"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – અનુપલબ્ધ"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> નો ઉપયોગ કરીએ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"તમારો દસ્તાવેજ પ્રિન્ટર સુધીના તેના માર્ગમાં એક અથવા વધુ સર્વર્સથી પસાર થઈ શકે છે."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"માફ કરશો, તે કામ કરતું નહોતું. ફરીથી પ્રયાસ કરો."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ફરી પ્રયાસ કરો"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"આ પ્રિન્ટર અત્યારે ઉપલબ્ધ નથી."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"પૂર્વાવલોકન પ્રદર્શિત કરી શકતાં નથી"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"પૂર્વાવલોકનની તૈયારી કરી રહ્યું છે..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index f75630e..377dc62 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"पुन: आरंभ करें"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटर के लिए कोई कनेक्शन नहीं"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – अनुपलब्ध"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> का उपयोग करें?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"प्रिंटर पर जाते समय आपका दस्तावेज़ एक या अधिक सर्वर से गुज़र सकता है."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"क्षमा करें, उससे बात नहीं बनी. पुन: प्रयास करें."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"फिर से प्रयास करें"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"यह प्रिंटर इस समय उपलब्ध नहीं है."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"पूर्वावलोकन प्रदर्शित नहीं किया जा सकता"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकन तैयार हो रहा है..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml
index bd29d02..8550be4 100644
--- a/packages/PrintSpooler/res/values-hr/strings.xml
+++ b/packages/PrintSpooler/res/values-hr/strings.xml
@@ -81,7 +81,6 @@
     <string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze s pisačem"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – zadatak nije dostupan"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li upotrijebiti uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Na putu do pisača vaš dokument može proći kroz jedan ili više poslužitelja."</string>
   <string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Nažalost, to nije uspjelo. Pokušajte ponovo."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Pokušajte ponovno"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Pisač trenutačno nije dostupan."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Pregled nije dostupan"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml
index 356cb76..20789a3 100644
--- a/packages/PrintSpooler/res/values-hu/strings.xml
+++ b/packages/PrintSpooler/res/values-hu/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Újraindítás"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nincs kapcsolat a nyomtatóval"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ismeretlen"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nem érhető el"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Használni szeretné a következő szolgáltatást: <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"A dokumentum áthaladhat egy vagy több szerveren, mielőtt a nyomtatóhoz érne."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Sajnáljuk, de nem sikerült. Próbálja újra."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Újra"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ez a nyomtató jelenleg nem érhető el."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Nem lehet megjeleníteni az előnézetet"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Előnézet előkészítése…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
index 2d10166..8950338 100644
--- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml
+++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Վերագործարկել"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Տպիչի հետ կապ չկա"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"անհայտ"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> տպիչն անհասանելի է"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Օգտագործե՞լ <xliff:g id="SERVICE">%1$s</xliff:g>-ը:"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Հնարավոր է՝ փաստաթուղթը մի քանի սերվերներով անցնի մինչ տպվելը:"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Չհաջողվեց: Նորից փորձեք:"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Կրկնել"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Տպիչն այս պահին հասանելի չէ:"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Նախադիտումը հնարավոր չէ"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Նախադիտումը պատրաստվում է…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml
index 8e20d27..9b72250 100644
--- a/packages/PrintSpooler/res/values-in/strings.xml
+++ b/packages/PrintSpooler/res/values-in/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Mulai Ulang"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Tidak ada sambungan ke printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"tak diketahui"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gunakan <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumen Anda dapat melewati satu atau beberapa server saat menuju printer."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Maaf, tidak berhasil. Coba lagi."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Coba lagi"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Saat ini printer ini tidak tersedia."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Tidak dapat menampilkan pratinjau"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Menyiapkan pratinjau..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml
index 73660fb..37abb5a 100644
--- a/packages/PrintSpooler/res/values-is-rIS/strings.xml
+++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Endurræsa"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Engin tenging við prentara"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"óþekkt"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ekki í boði"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Nota <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Skjalið gæti þurft að fara í gegnum einn eða fleiri þjóna á leið sinni til prentarans."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Þetta virkaði því miður ekki. Reyndu aftur."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Reyna aftur"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Þessi prentari er ekki í boði núna."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Ekki hægt að birta forskoðun"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Undirbýr forskoðun…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
index 46a570d8..dd4a8cb 100644
--- a/packages/PrintSpooler/res/values-it/strings.xml
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Riavvia"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nessun collegamento alla stampante"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"sconosciuto"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - non disponibile"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Utilizzare <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Il tuo documento potrebbe passare da uno o più server per raggiungere la stampante."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Non ha funzionato. Riprova."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Riprova"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Al momento la stampante non è disponibile."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Impossibile visualizzare l\'anteprima"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparazione anteprima…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
index c26c3d1..1d813bb 100644
--- a/packages/PrintSpooler/res/values-iw/strings.xml
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"הפעל מחדש"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"אין חיבור למדפסת"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"לא ידוע"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – לא זמינה"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"האם להשתמש ב-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ייתכן שהמסמך שלך יעבור בשרת אחד או יותר בדרכו למדפסת."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"מצטערים, אך זה לא עבד. נסה שוב."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"נסה שוב"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"המדפסת הזו אינה זמינה כעת."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"לא ניתן להציג תצוגה מקדימה"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"מכין תצוגה מקדימה…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml
index a6e243f..946052a 100644
--- a/packages/PrintSpooler/res/values-ja/strings.xml
+++ b/packages/PrintSpooler/res/values-ja/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"再試行"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"プリンタに接続されていません"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>–使用不可"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>を利用しますか?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ドキュメントは1つ以上のサーバーを経由してプリンタに送信されることがあります。"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"エラーです。もう一度お試しください。"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"再試行"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"現在このプリンターは使用できません。"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"プレビューを表示できません"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"プレビューを準備しています…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
index 2608ed48..94152b1 100644
--- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml
+++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"გადატვირთვა"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"პრინტერთან კავშირი არ არის"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"უცნობი"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – მიუწვდომელია"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"გსურთ, გამოიყენოთ <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"პრინტერამდე გზად დოკუმენტმა შეიძლება ერთი ან მეტი სერვერი გაიაროს."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"უკაცრავად, ვერ მოხერხდა. სცადეთ ისევ."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"გამეორება"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"პრინტერი ამჟამად მიუწვდომელია."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"გადახედვის ჩვენება ვერ ხერხდება"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"მზადდება გადახედვა…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
index def0c3c..2bc5ab6 100644
--- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
+++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Қайта бастау"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтермен байланыс жоқ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"белгісіз"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – қол жетімсіз"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> қолданылсын ба?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Құжат принтерге жеткенше бір немесе бірнеше серверден өтуі мүмкін."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Кешіріңіз, бұл нәтиже бермеді. Әрекетті қайталаңыз."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Қайталау"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Бұл принтер дәл қазір қол жетімді емес."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Алдын ала қарауды көрсету мүмкін емес"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Алдын ала қарау дайындалуда…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
index 24048cf..330edf5 100644
--- a/packages/PrintSpooler/res/values-km-rKH/strings.xml
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"ចាប់ផ្ដើម​ឡើងវិញ"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មាន​​​ការ​ភ្ជាប់​ទៅ​ម៉ាស៊ីន​បោះពុម្ព​"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"មិន​ស្គាល់"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – មិន​អាច​ប្រើ​បាន"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"ប្រើ <xliff:g id="SERVICE">%1$s</xliff:g> ឬ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ឯកសាររបស់អ្នកអាចនឹងឆ្លងកាត់ម៉ាស៊ីនមេមួយ ឬច្រើននៅពេលដែលវាធ្វើដំណើរទៅកាន់ម៉ាស៊ីនបោះពុម្ព។"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"សូម​ទោស វា​មិន​ដំណើរ​ការ​ទេ។ ព្យាយាម​ម្ដងទៀត។"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ព្យាយាម​ម្ដងទៀត"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ឥឡូវ​នេះ ម៉ាស៊ីន​បោះពុម្ព​នេះ​មិន​អាច​ប្រើ​បាន។"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"មិនអាចបង្ហាញការមើលជាមុនបានទេ"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"កំពុង​រៀបចំ​មើល​ជា​មុន…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
index af20965..f1cef86 100644
--- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"ಮರುಪ್ರಾರಂಭಿಸು"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ಮುದ್ರಕಕ್ಕೆ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ಅಜ್ಞಾತ"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ಬಳಸುವುದೇ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ನಿಮ್ಮ ಡಾಕ್ಯುಮೆಂಟ್‌ ಪ್ರಿಂಟರ್‌ಗೆ ಹೋಗುವ ಸಂದರ್ಭದಲ್ಲಿ ಒಂದು ಅಥವಾ ಅದಕ್ಕಿಂತ ಹೆಚ್ಚು ಸರ್ವರ್‌ಗಳ ಮೂಲಕ ಹಾದು ಹೋಗಬಹುದು."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"ಕ್ಷಮಿಸಿ, ಅದು ಕೆಲಸ ಮಾಡುತ್ತಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ಮರುಪ್ರಯತ್ನಿಸು"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ಈ ಪ್ರಿಂಟರ್ ಸದ್ಯಕ್ಕೆ ಲಭ್ಯವಿಲ್ಲ."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"ಪೂರ್ವವೀಕ್ಷಣೆ ಪ್ರದರ್ಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"ಪೂರ್ವವೀಕ್ಷಣೆ ತಯಾರಾಗುತ್ತಿದೆ…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml
index 0b297a2..d3cc967 100644
--- a/packages/PrintSpooler/res/values-ko/strings.xml
+++ b/packages/PrintSpooler/res/values-ko/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"다시 시작"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"프린터와 연결되지 않음"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"알 수 없음"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 사용할 수 없음"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>을(를) 사용할까요?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"문서가 프린터로 전송되는 중에 하나 이상의 서버를 통과할 수 있습니다."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"죄송합니다. 오류가 발생했습니다. 다시 시도해 보세요."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"다시 시도"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"현재 이 프린터를 사용할 수 없습니다."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"미리보기를 표시할 수 없음"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"미리보기 준비 중…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
index 85b2526..d84e5d8 100644
--- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml
+++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Кайра баштоо"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер менен байланыш жок"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"белгисиз"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – жеткиликтүү эмес"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> колдонулсунбу?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Принтерге жеткиче документиңиз бир же андан көп серверлерден өтүшү мүмкүн."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Кечиресиз, иштеген жок. Дагы бир жолу аракет кылып көрүңүз."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Дагы бир жолу аракет кылуу"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Учурда бул принтерди колдонуу мүмкүн эмес."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Алдын ала көрүнүшү көрсөтүлбөй жатат"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Алдын-ала көрүүгө даярданууда…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
index 81ace83..6a69053 100644
--- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml
+++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"ປິດເປີດໃໝ່"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ບໍ່ມີການເຊື່ອມຕໍ່ຫາເຄື່ອງພິມ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ບໍ່ຮູ້ຈັກ"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - ບໍ່ມີຢູ່"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"ໃຊ້ <xliff:g id="SERVICE">%1$s</xliff:g> ບໍ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ເອກະສານຂອງທ່ານອາດເດີນທາງຜ່ານໜຶ່ງ ຫຼື ຫຼາຍເຊີບເວີ ເພື່ອໄປຮອດເຄື່ອງພິມ."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"ຂໍ​ອະ​ໄພ, ໃຊ້​ບໍ່​ໄດ້. ໃຫ້​ລອງ​ໃໝ່​ອີກ​ເທື່ອ​ນຶ່ງ."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ລອງໃໝ່"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ບໍ່​ສາ​ມາດ​ໃຊ້ເຄື່ອງພິມ​ນີ້​ໃນ​ເວ​ລາ​ນີ້​ໄດ້."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"ບໍ່ສາມາດສະແດງຕົວຢ່າງໄດ້"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"ກຳ​ລັງ​ກະ​ກຽມ​ຕົວ​ຢ່າງ…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml
index 40bc7f1..ddcaba7 100644
--- a/packages/PrintSpooler/res/values-lt/strings.xml
+++ b/packages/PrintSpooler/res/values-lt/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Paleisti iš naujo"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nėra ryšio su spausdintuvu"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nežinoma"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ – nepasiekiama"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Naudoti „<xliff:g id="SERVICE">%1$s</xliff:g>“?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Kai dokumentas siunčiamas į spausdintuvą, jis gali būti perduodamas per vieną ar daugiau serverių."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Deja, tai neveikia. Bandykite dar kartą."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Bandykite dar kartą"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Šis spausdintuvas šiuo metu nepasiekiamas."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Nepavyksta pateikti peržiūros"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Ruošiama peržiūra…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml
index 11e689b..50ba32d 100644
--- a/packages/PrintSpooler/res/values-lv/strings.xml
+++ b/packages/PrintSpooler/res/values-lv/strings.xml
@@ -81,7 +81,6 @@
     <string name="restart" msgid="2472034227037808749">"Restartēt"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nav savienojuma ar printeri"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"nezināms"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — nav pieejams"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vai izmantot pakalpojumu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokuments, iespējams, tiek pārsūtīts caur vienu vai vairākiem serveriem, līdz tas nonāk līdz printerim."</string>
   <string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Diemžēl tas neizdevās. Mēģiniet vēlreiz."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Mēģināt vēlreiz"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Šis printeris šobrīd nav pieejams."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Nevar attēlot priekšskatījumu"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Notiek priekšskatījuma sagatavošana..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
index bc2b498..a189042 100644
--- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml
+++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Рестартирај"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Нема поврзување со печатач"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - недостапен"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Користи <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"На пат до печатачот, документот може да помине преку еден или повеќе сервери."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"За жал, тоа не успеа. Обидете се повторно."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Обиди се повторно"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Овој печатач не е достапен во моментов."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Прегледот не може да се прикаже"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Се подготвува преглед…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
index ade7fb39..5625632 100644
--- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"പുനരാരംഭിക്കുക"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"പ്രിന്ററിൽ കണക്ഷനൊന്നുമില്ല"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"അജ്ഞാതം"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ലഭ്യമല്ല"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> ഉപയോഗിക്കണോ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"നിങ്ങളുടെ പ്രമാണം പ്രിന്ററിലേക്ക് പോകുന്നതിനിടെ അത് ഒന്നോ അതിലധികമോ സെർവറുകളിലൂടെ കടന്നുപോകാനിടയുണ്ട്."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"ക്ഷമിക്കണം, അത് പ്രവർത്തിച്ചില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ഈ പ്രിന്ററർ ഇപ്പോൾ ലഭ്യമല്ല."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"പ്രിവ്യൂ കാണിക്കാൻ കഴിയില്ല"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"പ്രിവ്യൂ തയ്യാറാക്കുന്നു…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
index 133d88c..7797944 100644
--- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml
+++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Дахин эхлүүлэх"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер холбогдоогүй байна"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"тодорхойгүй"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ашиглах боломжгүй"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>-г ашиглах уу?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Таны документ хэвлэгчид иртэл нэг эсвэл хэд хэдэн серверээр дамжина."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Уучлаарай, ажилласангүй. Дахин оролдоно уу."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Дахин оролдох"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Одоо хэвлэгч ашиглах боломжгүй."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Урьдчилан үзүүлэх боломжгүй"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Урьдчилан харахыг бэлтгэж байна…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
index 2b3b29f..ee09db2 100644
--- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"रीस्टार्ट करा"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटरवर कोणतेही कनेक्‍शन नाही"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – अनुपलब्‍ध"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> वापरायची?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"आपला दस्तऐवज प्रिंटरपर्यंत पोहचण्‍यापूर्वी एक किंवा अधिक सर्व्हरद्वारे जाऊ शकतो."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"क्षमस्व, त्याने कार्य केले नाही. पुन्हा प्रयत्न करा."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"पुन्हा प्रयत्न करा"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"हा प्रिंटर आत्ता उपलब्ध नाही."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"पूर्वावलोकन प्रदर्शित करू शकत नाही"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकनाची तयारी करत आहे..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
index 73104e1..4042c71 100644
--- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml
+++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Mulakan semula"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Tiada sambungan ke pencetak"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"tidak diketahui"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gunakan <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumen anda mungkin melalui satu atau beberapa pelayan dalam perjalanan ke pencetak."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Maaf, itu tidak berjaya. Cuba lagi."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Cuba semula"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Pencetak ini tidak tersedia sekarang."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Tidak dapat memaparkan pratonton"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Menyediakan pratonton..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml
index 8cec068..f34ca67 100644
--- a/packages/PrintSpooler/res/values-my-rMM/strings.xml
+++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"အစက ပြန်စရန်"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"စာထုတ်စက်နဲ့ ဆက်သွယ်ထားမှု မရှိပါ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"အကြောင်းအရာ မသိရှိ"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – မတွေ့ရှိပါ"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ကိုသုံးမလား။"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"သင်၏ စာရွက်စာတမ်းများသည် ပရင်တာထံသို့ သွားစဉ် ဆာဗာ တစ်ခု သို့မဟုတ် ပိုများပြီး ဖြတ်ကျော်နိုင်ရသည်။"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"ဆော်ရီး၊ အဲဒါ အလုပ်မဖြစ်ခဲ့ပါ။ ထပ် စမ်းပါ။"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ထပ်စမ်း"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ဒီပရင်တာမှာ ယခုအချိန်မှာ မရနိုင်ပါ။"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"အစမ်းကြည့်ခြင်းကို ပြသ၍မရပါ"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"အစမ်းကြည့်ရန် ပြင်ဆင်နေ…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml
index 0a6f6c3..6b74765 100644
--- a/packages/PrintSpooler/res/values-nb/strings.xml
+++ b/packages/PrintSpooler/res/values-nb/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Start på nytt"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse med skriveren"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ukjent"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – utilgjengelig"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vil du bruke <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumentet ditt kan gå via flere tjenere før det når skriveren."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Beklager, det fungerte ikke. Prøv på nytt."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Prøv på nytt"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Denne skriveren er ikke tilgjengelig akkurat nå."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Kan ikke vise forhåndsvisningen"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Forbereder forhåndsvisningen …"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
index 5af3a04..8e8bf15 100644
--- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml
+++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"पुनःस्टार्ट गर्नुहोस्"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिन्टरमा कुनै जडान छैन"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - अनुपलब्ध"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्ने हो?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"तपाईँको कागजात प्रिन्टरमा जाँदा यसको मार्गमा एक वा धेरै सर्भरहरू पार हुनसक्छन्।"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"माफ गर्नुहोस्, त्यसले काम गरेन। पुनः प्रयास गर्नुहोस्।"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"पुनःप्रयास गर्नुहोस्"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"यो प्रिन्टर अहिले उपलब्ध छैन।"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"पूर्वावलोकनलाई प्रदर्शन गर्न सक्दैन"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"पूर्वावलोकन तयारी..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
index 4afdb86..3c65d8a 100644
--- a/packages/PrintSpooler/res/values-nl/strings.xml
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Opnieuw starten"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niet beschikbaar"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> gebruiken?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Je document kan via een of meer servers naar de printer worden verzonden."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Dat werkte niet. Probeer het opnieuw."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Opnieuw proberen"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Deze printer is momenteel niet beschikbaar."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Kan voorbeeld niet weergeven"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Voorbeeld voorbereiden…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-pa-rIN/strings.xml b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
index 1886ef5..934123b 100644
--- a/packages/PrintSpooler/res/values-pa-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-pa-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"ਰੀਸਟਾਰਟ ਕਰੋ"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ਪ੍ਰਿੰਟਰ ਲਈ ਕੋਈ ਕਨੈਕਸ਼ਨ ਨਹੀਂ"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ਅਗਿਆਤ"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ਅਣਉਪਲਬਧ"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"ਕੀ <xliff:g id="SERVICE">%1$s</xliff:g> ਵਰਤਣੀ ਹੈ?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ਤੁਹਾਡਾ ਦਸਤਾਵੇਜ਼ ਪ੍ਰਿੰਟਰ ਵਿੱਚ ਜਾਣ ਲਈ ਇੱਕ ਜਾਂ ਦੋ ਸਰਵਰਾਂ ਵਿੱਚੋਂ ਲੰਘਦਾ ਹੈ।"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"ਮਾਫ਼ ਕਰਨਾ, ਉਸਨੇ ਲਾਭਕਾਰੀ ਨਹੀਂ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ਇਹ ਪ੍ਰਿੰਟਰ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"ਝਲਕ ਨਹੀਂ ਵਿਖਾਈ ਜਾ ਸਕਦੀ"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"ਪ੍ਰੀਵਿਊ ਦੀ ਤਿਆਰੀ ਕਰ ਰਿਹਾ ਹੈ…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml
index 45649bb..80b6070 100644
--- a/packages/PrintSpooler/res/values-pl/strings.xml
+++ b/packages/PrintSpooler/res/values-pl/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Od nowa"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Brak połączenia z drukarką"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"brak informacji"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niedostępne"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Użyć usługi <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Zanim dokument dotrze do drukarki, może przejść przez jeden lub kilka serwerów."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"To nie zadziałało. Spróbuj jeszcze raz."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Ponów próbę"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Drukarka nie jest teraz dostępna."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Nie można wyświetlić podglądu"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Przygotowuję podgląd…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
index 58eb24f..4bd1161 100644
--- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Seu documento pode passar por um ou mais servidores até chegar à impressora."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Falhou. Tente novamente."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Tentar novamente"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impressora não está disponível no momento."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Não é possível exibir a visualização"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando visualização…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index 370bbb9..7660c5c 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem ligação à impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponível"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Pretende utilizar o <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"O seu documento pode passar por um ou mais servidores no respetivo caminho para a impressora."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Lamentamos, mas isso não funcionou. Tente novam."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Tentar novamente"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impressora não está atualmente disponível."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Não é possível apresentar a pré-visualização"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"A preparar a pré-visualização..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml
index 58eb24f..4bd1161 100644
--- a/packages/PrintSpooler/res/values-pt/strings.xml
+++ b/packages/PrintSpooler/res/values-pt/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Usar <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Seu documento pode passar por um ou mais servidores até chegar à impressora."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Falhou. Tente novamente."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Tentar novamente"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impressora não está disponível no momento."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Não é possível exibir a visualização"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando visualização…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml
index 1097d56..dd38c31 100644
--- a/packages/PrintSpooler/res/values-ro/strings.xml
+++ b/packages/PrintSpooler/res/values-ro/strings.xml
@@ -81,7 +81,6 @@
     <string name="restart" msgid="2472034227037808749">"Reporniți"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Nu există conexiune la o imprimantă"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"necunoscut"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - indisponibil"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Folosiți <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Documentul poate trece prin unul sau mai multe servere pe calea spre imprimantă."</string>
   <string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Ne pare rău, operațiunea nu a reușit. Încercați din nou."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Reîncercați"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Această imprimantă nu este disponibilă momentan."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Previzualizarea nu se poate afișa"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Se pregătește previzualizarea..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml
index 24b1e0d..6c074ed 100644
--- a/packages/PrintSpooler/res/values-ru/strings.xml
+++ b/packages/PrintSpooler/res/values-ru/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Повторить"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Нет связи с принтером"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"неизвестно"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступен"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Использовать <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ может пересылаться на принтер через несколько серверов."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Ошибка. Повторите попытку."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Повторить"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Принтер не готов."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Сбой предварительного просмотра"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Подготовка изображения…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml
index 707c151..8278aee 100644
--- a/packages/PrintSpooler/res/values-si-rLK/strings.xml
+++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"යළි අරඹන්න"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"මුද්‍රණ යන්ත්‍රය වෙත සම්බන්ධය නැත"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"නොදනී"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ලද නොහැක"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> භාවිත කරන්නද?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"ඔබගේ ලේඛනය මුද්‍රණ යන්ත්‍රයට යන අතරතුර සේවාදායක එකක් හෝ කිහිපයක් හරහා යා හැක."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"කණගාටුයි, එය වැඩ නොකරයි. නැවත උත්සහ කරන්න."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"නැවත උත්සාහ කරන්න"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"දැන් මෙම මුද්‍රණ යන්ත්‍රය නොපවතී."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"පෙරදසුන සංදර්ශනය කළ නොහැකිය"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"පෙරදසුන සූදානම් කරමින්…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml
index 1f13b54..610fe99 100644
--- a/packages/PrintSpooler/res/values-sk/strings.xml
+++ b/packages/PrintSpooler/res/values-sk/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Spustiť znova"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Žiadne pripojenie k tlačiarni"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"neznáme"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie je k dispozícii"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Použiť službu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Skôr ako sa váš dokument dostane do tlačiarne, môže prejsť jedným alebo viacerými servermi."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Je nám to ľúto, nefungovalo to. Skúste to znova."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Opakovať"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Táto tlačiareň nie je momentálne k dispozícii."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Ukážka sa nedá zobraziť"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Pripravuje sa ukážka..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml
index 3f8a5e6..b5124b4 100644
--- a/packages/PrintSpooler/res/values-sl/strings.xml
+++ b/packages/PrintSpooler/res/values-sl/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Začni znova"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ni povezave s tiskalnikom"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"neznano"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ni na voljo"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite uporabiti storitev <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokument gre lahko na poti do tiskalnika skozi enega ali več strežnikov."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"To žal ni delovalo. Poskusite znova."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Poskusi znova"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ta tiskalnik trenutno ni na voljo."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Predogleda ni mogoče prikazati"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Priprava predogleda …"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-sq-rAL/strings.xml b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
index 0b843d7..27bbbf9 100644
--- a/packages/PrintSpooler/res/values-sq-rAL/strings.xml
+++ b/packages/PrintSpooler/res/values-sq-rAL/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Rifillo"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printeri nuk është i lidhur"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"e panjohur"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nuk mundësohet"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Përdor <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokumenti mund të kalojë përmes një ose shumë serverëve deri te printeri."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Na vjen keq, nuk funksionoi! Provo përsëri."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Provo sërish"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ky printer nuk mund të përdoret tani."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Nuk mund të shfaqet paraafishimi"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Po përgatit shikimin paraprak…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index 8baa23c..ea6fcb7 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -81,7 +81,6 @@
     <string name="restart" msgid="2472034227037808749">"Поново покрени"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Нема везе са штампачем"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступан"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Желите ли да користите <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Документ може да прође кроз један или више сервера на путу до штампача."</string>
   <string-array name="color_mode_labels">
@@ -101,5 +100,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Жао нам је, ово није успело. Покушајте поново."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Покушајте поново"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Овај штампач тренутно није доступан."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Није успео приказ прегледа"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Припрема прегледа..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml
index 64b6b20..c909e19 100644
--- a/packages/PrintSpooler/res/values-sv/strings.xml
+++ b/packages/PrintSpooler/res/values-sv/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Starta om"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen anslutning till skrivaren"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"okänt"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – inte tillgänglig"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Vill du använda <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"På vägen till skrivaren kan dokumentet passera en eller flera servrar."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Det fungerade tyvärr inte. Försök igen."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Försök igen"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Den här skrivaren är inte tillgänglig just nu."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Det gick inte att visa förhandsgranskningen"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Förbereder förhandsvisning ..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml
index b3ffa71..bd14117 100644
--- a/packages/PrintSpooler/res/values-sw/strings.xml
+++ b/packages/PrintSpooler/res/values-sw/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Anzisha upya"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Hakuna muunganisho kwa printa"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"haijulikani"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - haipatikani"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Ungependa kutumia <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Huenda hati yako ikapitia seva moja au zaidi kabla ya kufika kwenye printa."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Samahani, hiyo haikufanya kazi. Jaribu tena."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Jaribu tena"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Printa hii haipatikani kwa sasa."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Haiwezi kupakia onyesho la kuchungulia"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Inaandaa onyesho la kuchungulia..."</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
index 7ae3cbc..782ebf2 100644
--- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"மீண்டும் தொடங்கு"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"அச்சுப்பொறியுடன் இணைக்கப்படவில்லை"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"அறியப்படாதது"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – இல்லை"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ஐப் பயன்படுத்தவா?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"உங்கள் ஆவணம் பிரிண்டருக்குச் செல்லும் வழியில் ஒன்று அல்லது அதற்கு மேற்பட்ட சேவையகங்களைக் கடந்து செல்லக்கூடும்."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"செயல்படவில்லை. மீண்டும் முயலவும்."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"மீண்டும் முயலவும்"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"இப்போது பிரிண்டர் இல்லை."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"மாதிரிக்காட்சியைக் காட்ட முடியவில்லை"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"மாதிரிக்காட்சியைத் தயார்படுத்துகிறது…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml
index 9e8dea2..ca393c839 100644
--- a/packages/PrintSpooler/res/values-te-rIN/strings.xml
+++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"పునఃప్రారంభించు"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ప్రింటర్‌కు కనెక్షన్ లేదు"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"తెలియదు"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – అందుబాటులో లేదు"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g>ని ఉపయోగించాలా?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"మీ పత్రం ప్రింటర్‌కు వెళ్లే మార్గంలో ఒకటి లేదా అంతకంటే ఎక్కువ సర్వర్‌ల గుండా వెళ్లవచ్చు."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"క్షమించండి, అది పని చేయలేదు. మళ్లీ ప్రయత్నించండి."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"మళ్లీ ప్రయత్నించు"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ఈ ప్రింటర్ ప్రస్తుతం అందుబాటులో లేదు."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"పరిదృశ్యాన్ని ప్రదర్శించడం సాధ్యపడలేదు"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"పరిదృశ్యం సిద్ధమవుతోంది…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml
index c623dd7..92b960e 100644
--- a/packages/PrintSpooler/res/values-th/strings.xml
+++ b/packages/PrintSpooler/res/values-th/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"เริ่มต้นใหม่"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ไม่มีการเชื่อมต่อไปยังเครื่องพิมพ์"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"ไม่ทราบ"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ไม่พร้อมใช้งาน"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"ใช้ <xliff:g id="SERVICE">%1$s</xliff:g> ไหม"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"เอกสารของคุณอาจต้องผ่านมากกว่าหนึ่งเซิร์ฟเวอร์ระหว่างส่งไปยังเครื่องพิมพ์"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"ขออภัย ไม่สามารถใช้งานได้ ลองอีกครั้ง"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"ลองอีกครั้ง"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"เครื่องพิมพ์นี้ไม่พร้อมใช้งานในขณะนี้"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"ไม่สามารถแสดงตัวอย่าง"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"กำลังเตรียมการแสดงตัวอย่าง…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml
index 0494cf6..5a736599 100644
--- a/packages/PrintSpooler/res/values-tl/strings.xml
+++ b/packages/PrintSpooler/res/values-tl/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"I-restart"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Hindi nakakonekta sa printer"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"hindi alam"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – hindi available"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Gusto mo bang gamitin ang <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Bago ma-print ang iyong dokumento, maaari itong dumaan sa isa o higit pang mga server."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Paumanhin, hindi iyon gumana. Subukang muli."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Subukang muli"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Hindi available ang printer na ito sa ngayon."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Hindi maipakita ang preview"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Inihahanda ang preview…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml
index 2818f36..f17bc9d 100644
--- a/packages/PrintSpooler/res/values-tr/strings.xml
+++ b/packages/PrintSpooler/res/values-tr/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Yeniden başlat"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Yazıcı bağlantısı yok"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"bilinmiyor"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – kullanılamıyor"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> kullanılsın mı?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dokümanınız yazıcıya giderken bir veya daha fazla sunucudan geçebilir."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Maalesef bu işe yaramadı. Tekrar deneyin."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Yeniden dene"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Bu yazı şu anda kullanılamıyor."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Önizleme gösterilemiyor"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Önizleme hazırlanıyor…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml
index 41051af..9629ad3 100644
--- a/packages/PrintSpooler/res/values-uk/strings.xml
+++ b/packages/PrintSpooler/res/values-uk/strings.xml
@@ -82,7 +82,6 @@
     <string name="restart" msgid="2472034227037808749">"Перезапустити"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Немає з’єднання з принтером"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"невідомо"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" не доступне"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Увімкнути службу <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Коли ви надсилаєте документ на принтер, він може проходити через декілька серверів."</string>
   <string-array name="color_mode_labels">
@@ -102,5 +101,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"На жаль, сталася помилка. Повторіть спробу."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Повторити"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Цей принтер зараз недоступний."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Не вдалося відкрити попередній перегляд"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Підготовка до попереднього перегляду…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
index a94b16f..0d01ee2 100644
--- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml
+++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"دوبارہ شروع کریں"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"پرنٹر کے ساتھ کوئی کنکشن نہیں ہے"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"نامعلوم"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – دستیاب نہیں ہے"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> استعمال کریں؟"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"آپ کی دستاویز پرنٹر تک جاتے ہوئے ممکن ہے ایک یا زیادہ سرورز سے گزرے۔"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"معذرت، اس نے کام نہیں کیا۔ دوبارہ کوشش کریں۔"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"دوبارہ کوشش کریں"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"یہ پرنٹر ابھی دستیاب نہیں ہے۔"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"پیش منظر ڈسپلے نہیں ہو سکتا"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"پیش منظر کو تیار کیا جا رہا ہے…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index a6af5bd..1f379d9 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Qayta boshlash"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Printer ulanmagan"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"noma’lum"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – mavjud emas"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> xizmatidan foydalanilsinmi?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Hujjatingiz chop etilishidan oldin bir yoki bir necha serverlardan o‘tishi mumkin."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Kechirasiz, ishlamadi. Qayta urinib ko‘ring."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Qayta urinish"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Ushbu printer hozirda mavjud emas."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Oldindan ko‘rsatib bo‘lmaydi"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Dastlabki ko\'rishga tayyorlanmoqda…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml
index df9e1a4..b931557 100644
--- a/packages/PrintSpooler/res/values-vi/strings.xml
+++ b/packages/PrintSpooler/res/values-vi/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Bắt đầu lại"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Không có kết nối nào với máy in"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"không xác định"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – không khả dụng"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Sử dụng <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Tài liệu của bạn có thể đi qua một hoặc nhiều máy chủ trên đường đến máy in."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Rất tiếc, tính năng đó không hoạt động. Hãy thử lại."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Thử lại"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Máy in này hiện không khả dụng."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Không thể hiển thị bản xem trước"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Đang chuẩn bị xem trước…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
index fb30e44..ffc9f85 100644
--- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"重新开始"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"未与打印机建立连接"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"未知"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - 无法使用"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用<xliff:g id="SERVICE">%1$s</xliff:g>吗?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文档可能会通过一个或多个服务器发送至打印机。"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"抱歉,操作失败。请重试。"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"重试"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"该打印机目前无法使用。"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"无法显示预览"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"即将显示预览…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
index f7c8fc9..4411a23 100644
--- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"重新開始"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與打印機連線"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用 <xliff:g id="SERVICE">%1$s</xliff:g> 嗎?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文件可能會通過一部或多部伺服器才傳送至打印機。"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"很抱歉,行不通。請再試一次。"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"重試"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"這部打印機目前無法使用。"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"無法顯示預覽"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"正在準備預覽…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
index aa18f3c..98126a7 100644
--- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"重新開始"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與印表機建立連線"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"要使用「<xliff:g id="SERVICE">%1$s</xliff:g>」嗎?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"您的文件可能會透過一或多個伺服器輾轉傳送至印表機。"</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"很抱歉,無法執行這項操作。請再試一次。"</string>
     <string name="print_error_retry" msgid="1426421728784259538">"重試"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"這台印表機目前無法使用。"</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"無法顯示預覽畫面"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"正在準備預覽…"</string>
 </resources>
diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml
index 9cfcb33..f2b4990 100644
--- a/packages/PrintSpooler/res/values-zu/strings.xml
+++ b/packages/PrintSpooler/res/values-zu/strings.xml
@@ -80,7 +80,6 @@
     <string name="restart" msgid="2472034227037808749">"Qala kabusha"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"Akukho ukuxhumana kuphrinta"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"akwaziwa"</string>
-    <string name="printer_unavailable" msgid="2434170617003315690">"I-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ayitholakali"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"Sebenzisa i-<xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
     <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Idokhumenti yakho ingase idlule iseva eyodwa noma amaningi lapho iya kuphrinta."</string>
   <string-array name="color_mode_labels">
@@ -100,5 +99,6 @@
     <string name="print_error_default_message" msgid="8602678405502922346">"Uxolo, lokho akusebenzanga. Zama futhi."</string>
     <string name="print_error_retry" msgid="1426421728784259538">"Zama futhi"</string>
     <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Le phrinta ayitholakali khona manje."</string>
+    <string name="print_cannot_load_page" msgid="6179560924492912009">"Ayikwazi ukubonisa ukubuka kuqala"</string>
     <string name="print_preparing_preview" msgid="3939930735671364712">"Ilungiselela ukubuka kuqala…"</string>
 </resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/model/NotificationController.java
index 0210693..cd1d540 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/NotificationController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/NotificationController.java
@@ -208,7 +208,7 @@
             }
         }
 
-        CharSequence status = printJob.getStatus();
+        CharSequence status = printJob.getStatus(mContext.getPackageManager());
         if (status != null) {
             builder.setContentText(status);
         } else {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 18160ff..9b1ab0e 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -19,6 +19,7 @@
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.app.Service;
 import android.content.ComponentName;
 import android.content.Context;
@@ -575,19 +576,35 @@
         }
     }
 
-   /**
-    * Set the status for a print job.
-    *
-    * @param printJobId ID of the print job to update
-    * @param status the new status
-    */
-   public void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) {
-       synchronized (mLock) {
-           getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY).setStatus(status);
+    /**
+     * Set the status for a print job.
+     *
+     * @param printJobId ID of the print job to update
+     * @param status the new status
+     */
+    public void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) {
+        synchronized (mLock) {
+            getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY).setStatus(status);
 
-           mNotificationController.onUpdateNotifications(mPrintJobs);
-       }
-   }
+            mNotificationController.onUpdateNotifications(mPrintJobs);
+        }
+    }
+
+    /**
+     * Set the status for a print job.
+     *
+     * @param printJobId ID of the print job to update
+     * @param status the new status as a string resource
+     * @param appPackageName app package the resource belongs to
+     */
+    public void setStatus(@NonNull PrintJobId printJobId, @StringRes int status,
+            @Nullable CharSequence appPackageName) {
+        synchronized (mLock) {
+            getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY).setStatus(status, appPackageName);
+
+            mNotificationController.onUpdateNotifications(mPrintJobs);
+        }
+    }
 
     public boolean hasActivePrintJobsLocked() {
         final int printJobCount = mPrintJobs.size();
@@ -884,7 +901,7 @@
                         serializer.attribute(null, ATTR_PROGRESS, String.valueOf(progress));
                     }
 
-                    CharSequence status = printJob.getStatus();
+                    CharSequence status = printJob.getStatus(getPackageManager());
                     if (!TextUtils.isEmpty(status)) {
                         serializer.attribute(null, ATTR_STATUS, status.toString());
                     }
@@ -1041,7 +1058,9 @@
             try {
                 in = mStatePersistFile.openRead();
             } catch (FileNotFoundException e) {
-                Log.i(LOG_TAG, "No existing print spooler state.");
+                if (DEBUG_PERSISTENCE) {
+                    Log.d(LOG_TAG, "No existing print spooler state.");
+                }
                 return;
             }
             try {
@@ -1433,6 +1452,13 @@
             PrintSpoolerService.this.setStatus(printJobId, status);
         }
 
+        @Override
+        public void setStatusRes(@NonNull PrintJobId printJobId, @StringRes int status,
+                @NonNull CharSequence appPackageName) throws RemoteException {
+            PrintSpoolerService.this.setStatus(printJobId, status, appPackageName);
+        }
+
+
         public PrintSpoolerService getService() {
             return PrintSpoolerService.this;
         }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index bb34fcf..a24d664 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -2051,9 +2051,12 @@
             mDestinationSpinnerAdapter.unregisterDataSetObserver(mPrintersObserver);
         }
 
+        if (mSpoolerProvider != null) {
+            mSpoolerProvider.destroy();
+        }
+
         if (mState != STATE_INITIALIZING) {
             mProgressMessageController.cancel();
-            mSpoolerProvider.destroy();
             mPrintedDocument.finish();
             mPrintedDocument.destroy();
             mPrintPreviewController.destroy(new Runnable() {
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 406c9b7..93415c0 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"Tuis"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> gelede"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> oor"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Klein"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Verstek"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Groot"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Groter"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Grootste"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Gepasmaak (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index e4cd8b9..cf2a6ce 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"መነሻ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"ከ<xliff:g id="ID_1">%1$s</xliff:g> በፊት"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ቀርቷል"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ትንሽ"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ነባሪ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ትልቅ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ተለቅ ያለ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"በጣም ተለቅ ያለ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ብጁ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index ad87a89..e21b02c 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"الشاشة الرئيسية"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"قبل <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"يتبقى <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"صغير"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"افتراضي"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"كبير"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"أكبر"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"أكبر مستوى"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"مخصص (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index c141445..31d20a9 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"Əsas səhifə"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> əvvəl"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> qalıb"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kiçik"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Defolt"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Böyük"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Daha böyük"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Ən böyük"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Fərdi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 3e3cce0..4bd9b03 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Početni"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Pre <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mali"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Podrazumevano"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliki"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veći"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveći"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-be-rBY/strings.xml b/packages/SettingsLib/res/values-be-rBY/strings.xml
index 08aa3a0..ded4e41 100644
--- a/packages/SettingsLib/res/values-be-rBY/strings.xml
+++ b/packages/SettingsLib/res/values-be-rBY/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"Галоўная"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> таму назад"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Засталося <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Маленькі"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Стандартны"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Вялікі"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Большы"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Найвялікшы"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Карыстальніцкі (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 2dbeeac..e0641b1 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Начало"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Преди <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Оставащо време: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Малко"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"По подразбиране"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Голямо"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"По-голямо"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Най-голямо"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Персонализирано (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index eea4f06..5ca7d03 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"হোম"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> আগে"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ক্ষুদ্র"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ডিফল্ট"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"বড়"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"খুব বড়"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"বৃহত্তম"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"কাস্টম (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml
index cf9e4a4..dcce9a5 100644
--- a/packages/SettingsLib/res/values-bs-rBA/strings.xml
+++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"Početna stranica"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"prije <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Još otprilike <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malo"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Zadano"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veće"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveće"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 8d158ac..5106f5b 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Inici"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Fa <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Temps restant: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Petit"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminat"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Gran"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Més gran"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Màxim"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalitzat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 9e9abad..3d3dd6f 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Plocha"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"před <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Zbývající čas: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malé"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Výchozí"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Velké"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Větší"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Největší"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastní (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 659bd32..1f354b7 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Start"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> siden"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> tilbage"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Lille"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standard"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stor"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Større"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Størst"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tilpasset (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 67d0198..404b72b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Startseite"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Vor <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Noch <xliff:g id="ID_1">%1$s</xliff:g> verbleibend"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Klein"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standard"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Groß"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Größer"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Am größten"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Benutzerdefiniert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 263703c..52988f6 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Αρχική οθόνη"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Πριν από <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Απομένουν <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Μικρά"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Προεπιλογή"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Μεγάλα"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Πιο μεγάλα"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Μεγαλύτερα"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Προσαρμοσμένη (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 7a00eb7..b2df062 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Home"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 7a00eb7..b2df062 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Home"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 7a00eb7..b2df062 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Home"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Small"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Large"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Larger"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Largest"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index b45753d..dd7ee4d 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Página principal"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Hace <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Falta <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeño"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminado"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Más grande"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Máximo"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 1e36088..0cc6cb6 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Inicio"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Hace <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Tiempo restante: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeño"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminado"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Más grande"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Lo más grande posible"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index cb0e7f2..a275b1a 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Avaekraan"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> tagasi"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> on jäänud"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Väike"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Vaikimisi"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Suur"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Suurem"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Suurim"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kohandatud (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index f09949f..2556224 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Hasierako pantaila"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Duela <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> guztiz kargatu arte"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Txikia"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Lehenetsia"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Handia"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Oso handia"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Handiena"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pertsonalizatua (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index c621be3..a1393e8 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"صفحه اصلی"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> قبل"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> باقی مانده است"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"کوچک"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"پیش‌فرض"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"بزرگ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"بزرگ‌تر"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"بزرگ‌ترین"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"سفارشی (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 8ec2f6e..3d8ac98 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Aloitusnäyttö"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> sitten"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> jäljellä"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pieni"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Oletus"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Suuri"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Suurempi"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Suurin"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Muokattu (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index e2de253..4eb3a427 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Accueil"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Il y a <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Durée restante :<xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Petite"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Par défaut"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Plus grande"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"La plus grande"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisée (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index e3dd87a..efb10ec 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Accueil"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Il y a <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Il reste <xliff:g id="ID_1">%1$s</xliff:g>."</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Petit"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Par défaut"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grand"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Plus grand"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Le plus grand"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisé (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index e75fee6..3d61e21 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Inicio"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Hai <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Tempo restante: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeno"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predeterminado"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Máis grande"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"O máis grande"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 38b6089..628b4be 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"હોમ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> પહેલાં"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> બાકી"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"નાનું"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ડિફોલ્ટ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"મોટું"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"વધુ મોટું"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"સૌથી મોટું"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"કસ્ટમ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index dce538b..047c7db 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"होम"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पहले"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> शेष"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"छोटा"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"डिफ़ॉल्ट"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"बड़ा"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"अधिक बड़ा"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"सबसे बड़ा"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"कस्टम (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 7a2acd8..f5ad6d2 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Početni zaslon"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Prije <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malo"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Zadano"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Veće"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najveće"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeno (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 426cff4..7279c9c 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Főoldal"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Ennyi ideje: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> van hátra"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kicsi"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Alapértelmezett"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Nagy"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Nagyobb"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Legnagyobb"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egyéni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index 8c62221..afde9b5 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"Գլխավոր էջ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> առաջ"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Մնացել է <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Փոքր"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Կանխադրված"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Մեծ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Ավելի մեծ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Ամենամեծ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Հատուկ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 662bb22..24fd0f17 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Layar Utama"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> lalu"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Tersisa <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kecil"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Besar"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lebih besar"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Terbesar"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"(<xliff:g id="DENSITYDPI">%d</xliff:g>) khusus"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 30440da..e22dbe0 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Heim"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Fyrir <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> eftir"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Lítið"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Sjálfgefið"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stórt"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Stærra"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Stærst"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Sérsniðið (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 40802bc..84ff78a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Home page"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> fa"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> rimanenti"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Piccolo"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predefinito"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Più grande"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Massimo"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizzato (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index a651a3a..b1d4eea 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"דף הבית"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"לפני <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"נשארו <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"קטן"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ברירת מחדל"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"גדול"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"יותר גדול"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"הכי גדול"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"מותאם אישית (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index e17db51..2556d99 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -318,4 +318,10 @@
     <string name="home" msgid="8263346537524314127">"ホーム"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"あと <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"デフォルト"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"特大"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"カスタム(<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 11fa8a6..1c05631 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"მთავარი"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"გავიდა <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"დარჩენილია <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"პატარა"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ნაგულისხმევი"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"დიდი"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"უფრო დიდი"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"უდიდესი"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"მორგებული (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index aae7449..fdd3f95 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Негізгі бет"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> бұрын"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> қалды"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Кішкентай"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Әдепкі"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Үлкен"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Үлкенірек"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Ең үлкен"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Арнаулы (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index 4373c43..2cafa29 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"ដើម"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> មុន"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"នៅសល់ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"តូច"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"លំនាំដើម"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ធំ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ធំជាង"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ធំបំផុត"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ផ្ទាល់ខ្លួន (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index f0d63fb..7c90cca 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"ಮುಖಪುಟ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ಹಿಂದೆ"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ಸಣ್ಣದು"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ಡಿಫಾಲ್ಟ್"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ದೊಡ್ಡದು"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ಸ್ವಲ್ಪ ದೊಡ್ಡ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ದೊಡ್ಡ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ಕಸ್ಟಮ್ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index a8b6c36..035793e 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"홈"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> 전"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> 남음"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"작게"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"기본"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"크게"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"더 크게"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"가장 크게"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"맞춤(<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 6491d3c..9956271 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"Башкы бет"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> мурун"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> калды"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Кичине"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Демейки"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Чоң"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Чоңураак"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Эң чоң"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ыңгайлаштырылган (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index cf90c4b..f158d44 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"​ໜ້າຫຼັກ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ກ່ອນນີ້"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"ຍັງເຫຼືອ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ນ້ອຍ"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ຄ່າເລີ່ມຕົ້ນ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ໃຫຍ່"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ໃຫຍ່ກວ່າ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ໃຫຍ່ທີ່ສຸດ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ປັບແຕ່ງເອງ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index fd245f3..d5cea8e 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Pagrindinis ekranas"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Prieš <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Liko <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mažas"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Numatytasis"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Didelis"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Didesnis"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Didžiausias"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tinkintas (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index b470fb54..ea6f4f9 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Sākums"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Pirms šāda laika: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Atlikušais laiks: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mazs"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Noklusējuma"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Liels"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lielāks"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Vislielākais"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pielāgots (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 7592cd3..e954cdf1 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Почетна страница"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Пред <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Преостанаа <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Мал"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Стандардно"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Голем"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Поголем"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Најголем"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Приспособен (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 13a7013..d6a28cd 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"ഹോം"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> മുമ്പ്"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ചെറുത്"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ഡിഫോൾട്ട്"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"വലുത്"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"കൂടുതൽ വലുത്"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ഏറ്റവും വലുത്"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ഇഷ്ടാനുസൃതം ( <xliff:g id="DENSITYDPI">%d</xliff:g> )"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index a77e32e..d989ef8 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Нүүр"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> өмнө"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> үлдсэн"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Жижиг"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Өгөгдмөл"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Том"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Илүү том"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Хамгийн том"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Тогтмол утга (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index 4f12e46..eee940b 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"मुख्यपृष्ठ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पूर्वी"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> शिल्लक"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"लहान"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"डीफॉल्ट"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"मोठा"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"आणखी मोठा"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"सर्वात मोठा"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"सानुकूल करा (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 6ba7d20..ea79a468 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Skrin Utama"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> yang lalu"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> lagi"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kecil"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Lalai"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Besar"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lebih besar"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Terbesar"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tersuai (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index 5c1a5ee..74e0f29 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"ပင်မ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"ပြီးခဲ့သည့် <xliff:g id="ID_1">%1$s</xliff:g> က"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ကျန်ပါသည်"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"သေး"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"မူရင်း"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ကြီး"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ပိုကြီး"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"အကြီးဆုံး"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"စိတ်ကြိုက် (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index de6faf4..1a0b468 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Startside"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> siden"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> gjenstår"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Liten"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standard"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stor"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Større"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Størst"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egendefinert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index 47ec137..3f39931 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"गृह"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पहिले"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> बाँकी"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"सानो"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"पूर्वनिर्धारित"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ठूलो"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"अझ ठूलो"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"सबैभन्दा ठूलो"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"अनुकूलन (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 9f72db5..301e327 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Startpagina"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> geleden"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> resterend"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Klein"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standaard"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Groot"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Groter"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Grootst"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Aangepast (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index 8625b90..883fda0 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ਪਹਿਲਾਂ"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ਬਾਕੀ"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ਛੋਟਾ"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ਵੱਡਾ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ਥੋੜ੍ਹਾ ਵੱਡਾ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ਸਭ ਤੋਂ ਵੱਡਾ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index b4c030d..8aad98b1 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Ekran główny"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> temu"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Pozostało <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Małe"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Domyślne"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Duże"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Większe"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Największe"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Niestandardowe (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index e76535a..c05458b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Início"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> atrás"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> restante(s)"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequena"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Padrão"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Muito grande"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Maior"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 7e4744c..402bc86 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Página inicial"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Há <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Resta(m) <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequeno"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predefinição"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Maior"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"O maior"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index e76535a..c05458b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Início"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> atrás"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> restante(s)"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Pequena"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Padrão"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Grande"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Muito grande"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Maior"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 5b712d0..d5e0769 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Ecranul principal"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Acum <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Timp rămas: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Mic"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Prestabilit"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Mare"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Mai mare"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Cel mai mare"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index b233c4cb7..7ad9f16 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Главная"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> назад"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Осталось <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Мелкий"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"По умолчанию"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Крупный"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Очень крупный"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Максимальный"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Другой (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index c8af144..b3ead79 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"මුල් පිටුව"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>කට පෙර"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g>ක් ඉතිරිය"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"කුඩා"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"පෙරනිමි"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"විශාල"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"වඩා විශාල"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"විශාලතම"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"අභිරුචි (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 2c7a3b7..e5c9805 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Domov"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"pred <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Zostáva <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malé"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predvolená"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veľké"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Väčšie"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najväčšie"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastné (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 62797c3..8257e3c 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Začetni zaslon"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Pred toliko časa: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Še <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Majhno"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Privzeto"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veliko"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Večje"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Največje"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Po meri (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index 0a069de..4a67348 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Kreu"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> më parë"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> të mbetura"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"I vogël"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"I parazgjedhur"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"I madh"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Më i madh"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Më i madhi"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"I personalizuar (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 61a87b5..eaf7ac5 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Почетни"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Пре <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Још <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Мали"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Подразумевано"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Велики"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Већи"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Највећи"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Прилагођени (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 1de7317..b019672 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Startsida"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"för <xliff:g id="ID_1">%1$s</xliff:g> sedan"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> kvar"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Små"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Standardinställning"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Stora"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Större"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Störst"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Anpassad (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index c02c256..3daa90f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Mwanzo"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"Zimepita <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Zimesalia <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Ndogo"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Chaguo-msingi"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Kubwa"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Kubwa kiasi"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Kubwa zaidi"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kiwango maalum (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index d28fe75..574d105 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"முகப்பு"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> முன்"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> உள்ளது"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"சிறியது"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"இயல்பு"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"பெரியது"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"கொஞ்சம் பெரியது"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"மிகப் பெரியது"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"தனிப்பயன் (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index 9b6694c..2389112 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"హోమ్"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> క్రితం"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> మిగిలి ఉంది"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"చిన్నగా"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"డిఫాల్ట్"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"పెద్దగా"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"చాలా పెద్దగా"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"అతి పెద్దగా"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"అనుకూలం (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 5880b98..5d7b1a3 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"หน้าแรก"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>ที่ผ่านมา"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"เหลือ <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"เล็ก"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ค่าเริ่มต้น"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ใหญ่"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ใหญ่ขึ้น"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ใหญ่ที่สุด"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"กำหนดเอง (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 3764d22..ef3dde7 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Home"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> na ang nakalipas"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> na lang"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Maliit"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Default"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Malaki"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Mas malaki"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Pinakamalaki"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 0a2c654..4b7490d 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Ana Ekran"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> önce"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> kaldı"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Küçük"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Varsayılan"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Büyük"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Daha büyük"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"En büyük"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Özel (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 5b88647..5e044c3 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Головний екран"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> тому"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Залишилося <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Малі елементи"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"За умовчанням"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Великі елементи"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Більші елементи"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Найбільші елементи"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Спеціальний масштаб (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index e066736..6d3c6c4 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"ہوم"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> قبل"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> باقی ہیں"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"چھوٹا"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ڈیفالٹ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"بڑا"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"قدرے بڑا"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"سب سے بڑا"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"حسب ضرورت (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index 23e8b0f..2311a66 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -317,4 +317,10 @@
     <string name="home" msgid="8263346537524314127">"Bosh ekran"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> oldin"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> qoldi"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Kichkina"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Birlamchi"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Katta"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Kattaroq"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Eng katta"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Moslashtirilgan (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 27dd482..dd1d482 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Màn hình chính"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> trước"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Còn <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Nhỏ"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Mặc định"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Lớn"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Lớn hơn"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Lớn nhất"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tùy chỉnh (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 73cd252..4117ae1 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"主屏幕"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"还剩 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"默认"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"较大"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自定义 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 944082f..1fb4c5e 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"主畫面"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"尚餘 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"預設"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"較大"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自訂 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index dc029d9..9c85f0e 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"主畫面"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"還剩 <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"小"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"預設"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"大"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"較大"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自訂 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 9ba957a..6017d68 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -316,4 +316,10 @@
     <string name="home" msgid="8263346537524314127">"Ekhaya"</string>
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> edlule"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> osele"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Okuncane"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Okuzenzakalelayo"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Okukhulu"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Okukhulu kakhulu"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Okukhulu kakhulu"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ngokwezifiso (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index a2a3fd3..fe3ef1a 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -812,4 +812,18 @@
     <!-- HTTP proxy settings. The hint text field for the hostname. -->
     <string name="proxy_hostname_hint" translatable="false">proxy.example.com</string>
 
+    <!-- Description for the screen zoom level that makes interface elements small. [CHAR LIMIT=24] -->
+    <string name="screen_zoom_summary_small">Small</string>
+    <!-- Description for the device's default screen zoom level. [CHAR LIMIT=24] -->
+    <string name="screen_zoom_summary_default">Default</string>
+    <!-- Description for the screen zoom level that makes interface elements large. [CHAR LIMIT=24] -->
+    <string name="screen_zoom_summary_large">Large</string>
+    <!-- Description for the screen zoom level that makes interface elements larger. [CHAR LIMIT=24] -->
+    <string name="screen_zoom_summary_very_large">Larger</string>
+    <!-- Description for the screen zoom level that makes interface elements largest. [CHAR LIMIT=24] -->
+    <string name="screen_zoom_summary_extremely_large">Largest</string>
+    <!-- Description for a custom screen zoom level. This shows the requested display
+         density in raw pixels per inch rather than using a relative description. [CHAR LIMIT=24] -->
+    <string name="screen_zoom_summary_custom">Custom (<xliff:g id="densityDpi" example="160">%d</xliff:g>)</string>
+
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index 3b818c8..0e3e0d5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -60,7 +60,7 @@
 public class StorageMeasurement {
     private static final String TAG = "StorageMeasurement";
 
-    private static final boolean LOCAL_LOGV = true;
+    private static final boolean LOCAL_LOGV = false;
     static final boolean LOGV = LOCAL_LOGV && Log.isLoggable(TAG, Log.VERBOSE);
 
     private static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
new file mode 100644
index 0000000..78d7c56
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.display;
+
+import com.android.settingslib.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.os.RemoteException;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.MathUtils;
+import android.view.Display;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
+
+import java.util.Arrays;
+
+/**
+ * Utility methods for working with display density.
+ */
+public class DisplayDensityUtils {
+    private static final String LOG_TAG = "DisplayDensityUtils";
+
+    /** Minimum increment between density scales. */
+    private static final float MIN_SCALE_INTERVAL = 0.09f;
+
+    /** Minimum density scale. This is available on all devices. */
+    private static final float MIN_SCALE = 0.85f;
+
+    /** Maximum density scale. The actual scale used depends on the device. */
+    private static final float MAX_SCALE = 1.50f;
+
+    /** Summary used for "default" scale. */
+    public static final int SUMMARY_DEFAULT = R.string.screen_zoom_summary_default;
+
+    /** Summary used for "custom" scale. */
+    private static final int SUMMARY_CUSTOM = R.string.screen_zoom_summary_custom;
+
+    /**
+     * Summaries for scales smaller than "default" in order of smallest to
+     * largest.
+     */
+    private static final int[] SUMMARIES_SMALLER = new int[] {
+            R.string.screen_zoom_summary_small
+    };
+
+    /**
+     * Summaries for scales larger than "default" in order of smallest to
+     * largest.
+     */
+    private static final int[] SUMMARIES_LARGER = new int[] {
+            R.string.screen_zoom_summary_large,
+            R.string.screen_zoom_summary_very_large,
+            R.string.screen_zoom_summary_extremely_large,
+    };
+
+    /**
+     * Minimum allowed screen dimension, corresponds to resource qualifiers
+     * "small" or "sw320dp". This value must be at least the minimum screen
+     * size required by the CDD so that we meet developer expectations.
+     */
+    private static final int MIN_DIMENSION_DP = 320;
+
+    private final String[] mEntries;
+    private final int[] mValues;
+
+    private final int mDefaultDensity;
+    private final int mCurrentIndex;
+
+    public DisplayDensityUtils(Context context) {
+        final int defaultDensity = DisplayDensityUtils.getDefaultDisplayDensity(
+                Display.DEFAULT_DISPLAY);
+        if (defaultDensity <= 0) {
+            mEntries = null;
+            mValues = null;
+            mDefaultDensity = 0;
+            mCurrentIndex = -1;
+            return;
+        }
+
+        final Resources res = context.getResources();
+        final DisplayMetrics metrics = res.getDisplayMetrics();
+        final int currentDensity = metrics.densityDpi;
+        int currentDensityIndex = -1;
+
+        // Compute number of "larger" and "smaller" scales for this display.
+        final int minDimensionPx = Math.min(metrics.widthPixels, metrics.heightPixels);
+        final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP;
+        final float maxScale = Math.min(MAX_SCALE, maxDensity / (float) defaultDensity);
+        final float minScale = MIN_SCALE;
+        final int numLarger = (int) MathUtils.constrain((maxScale - 1) / MIN_SCALE_INTERVAL,
+                0, SUMMARIES_LARGER.length);
+        final int numSmaller = (int) MathUtils.constrain((1 - minScale) / MIN_SCALE_INTERVAL,
+                0, SUMMARIES_SMALLER.length);
+
+        String[] entries = new String[1 + numSmaller + numLarger];
+        int[] values = new int[entries.length];
+        int curIndex = 0;
+
+        if (numSmaller > 0) {
+            final float interval = (1 - minScale) / numSmaller;
+            for (int i = numSmaller - 1; i >= 0; i--) {
+                // Round down to a multiple of 2 by truncating the low bit.
+                final int density = ((int) (defaultDensity * (1 - (i + 1) * interval))) & ~1;
+                if (currentDensity == density) {
+                    currentDensityIndex = curIndex;
+                }
+                entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]);
+                values[curIndex] = density;
+                curIndex++;
+            }
+        }
+
+        if (currentDensity == defaultDensity) {
+            currentDensityIndex = curIndex;
+        }
+        values[curIndex] = defaultDensity;
+        entries[curIndex] = res.getString(SUMMARY_DEFAULT);
+        curIndex++;
+
+        if (numLarger > 0) {
+            final float interval = (maxScale - 1) / numLarger;
+            for (int i = 0; i < numLarger; i++) {
+                // Round down to a multiple of 2 by truncating the low bit.
+                final int density = ((int) (defaultDensity * (1 + (i + 1) * interval))) & ~1;
+                if (currentDensity == density) {
+                    currentDensityIndex = curIndex;
+                }
+                values[curIndex] = density;
+                entries[curIndex] = res.getString(SUMMARIES_LARGER[i]);
+                curIndex++;
+            }
+        }
+
+        final int displayIndex;
+        if (currentDensityIndex >= 0) {
+            displayIndex = currentDensityIndex;
+        } else {
+            // We don't understand the current density. Must have been set by
+            // someone else. Make room for another entry...
+            int newLength = values.length + 1;
+            values = Arrays.copyOf(values, newLength);
+            values[curIndex] = currentDensity;
+
+            entries = Arrays.copyOf(entries, newLength);
+            entries[curIndex] = res.getString(SUMMARY_CUSTOM, currentDensity);
+
+            displayIndex = curIndex;
+        }
+
+        mDefaultDensity = defaultDensity;
+        mCurrentIndex = displayIndex;
+        mEntries = entries;
+        mValues = values;
+    }
+
+    public String[] getEntries() {
+        return mEntries;
+    }
+
+    public int[] getValues() {
+        return mValues;
+    }
+
+    public int getCurrentIndex() {
+        return mCurrentIndex;
+    }
+
+    public int getDefaultDensity() {
+        return mDefaultDensity;
+    }
+
+    /**
+     * Returns the default density for the specified display.
+     *
+     * @param displayId the identifier of the display
+     * @return the default density of the specified display, or {@code -1} if
+     *         the display does not exist or the density could not be obtained
+     */
+    private static int getDefaultDisplayDensity(int displayId) {
+       try {
+           final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+           return wm.getInitialDisplayDensity(displayId);
+       } catch (RemoteException exc) {
+           return -1;
+       }
+    }
+
+    /**
+     * Asynchronously applies display density changes to the specified display.
+     *
+     * @param displayId the identifier of the display to modify
+     */
+    public static void clearForcedDisplayDensity(final int displayId) {
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+                    wm.clearForcedDisplayDensity(displayId);
+                } catch (RemoteException exc) {
+                    Log.w(LOG_TAG, "Unable to clear forced display density setting");
+                }
+            }
+        });
+    }
+
+    /**
+     * Asynchronously applies display density changes to the specified display.
+     *
+     * @param displayId the identifier of the display to modify
+     * @param density the density to force for the specified display
+     */
+    public static void setForcedDisplayDensity(final int displayId, final int density) {
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+                    wm.setForcedDisplayDensity(displayId, density);
+                } catch (RemoteException exc) {
+                    Log.w(LOG_TAG, "Unable to save forced display density setting");
+                }
+            }
+        });
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index ce69c5a..64910fd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -41,6 +41,7 @@
 import android.widget.ListView;
 import android.widget.Toolbar;
 import com.android.settingslib.R;
+import com.android.settingslib.applications.InterestingConfigChanges;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -55,6 +56,7 @@
 
     private static List<DashboardCategory> sDashboardCategories;
     private static HashMap<Pair<String, String>, Tile> sTileCache;
+    private static InterestingConfigChanges sConfigTracker;
 
     private final PackageReceiver mPackageReceiver = new PackageReceiver();
     private final List<CategoryListener> mCategoryListeners = new ArrayList<>();
@@ -208,6 +210,7 @@
     public List<DashboardCategory> getDashboardCategories() {
         if (sDashboardCategories == null) {
             sTileCache = new HashMap<>();
+            sConfigTracker = new InterestingConfigChanges();
             sDashboardCategories = TileUtils.getCategories(this, sTileCache);
         }
         return sDashboardCategories;
@@ -267,6 +270,9 @@
     private class CategoriesUpdater extends AsyncTask<Void, Void, List<DashboardCategory>> {
         @Override
         protected List<DashboardCategory> doInBackground(Void... params) {
+            if (sConfigTracker.applyNewConfig(getResources())) {
+                sTileCache.clear();
+            }
             return TileUtils.getCategories(SettingsDrawerActivity.this, sTileCache);
         }
 
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index c9582ea..c131fa5 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -409,10 +409,11 @@
 
         final BugreportInfo info = new BugreportInfo(mContext, id, pid, name, max);
         if (mProcesses.indexOfKey(id) >= 0) {
+            // BUGREPORT_STARTED intent was already received; ignore it.
             Log.w(TAG, "ID " + id + " already watched");
-        } else {
-            mProcesses.put(info.id, info);
+            return true;
         }
+        mProcesses.put(info.id, info);
         // Take initial screenshot.
         takeScreenshot(id, false);
         updateProgress(info);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 589eac6..9839446 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -263,6 +263,14 @@
             </intent-filter>
         </activity>
 
+        <activity
+            android:name=".stackdivider.ForcedResizableInfoActivity"
+            android:theme="@style/ForcedResizableTheme"
+            android:excludeFromRecents="true"
+            android:stateNotNeeded="true"
+            android:exported="false">
+        </activity>
+
         <!-- Callback for dismissing screenshot notification after a share target is picked -->
         <receiver android:name=".screenshot.GlobalScreenshot$TargetChosenReceiver"
                   android:process=":screenshot"
diff --git a/packages/SystemUI/res/anim/forced_resizable_enter.xml b/packages/SystemUI/res/anim/forced_resizable_enter.xml
new file mode 100644
index 0000000..01b8fdb
--- /dev/null
+++ b/packages/SystemUI/res/anim/forced_resizable_enter.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromAlpha="0.0"
+    android:toAlpha="1.0"
+    android:interpolator="@android:interpolator/linear_out_slow_in"
+    android:duration="280" />
diff --git a/packages/SystemUI/res/anim/forced_resizable_exit.xml b/packages/SystemUI/res/anim/forced_resizable_exit.xml
new file mode 100644
index 0000000..6f316a7
--- /dev/null
+++ b/packages/SystemUI/res/anim/forced_resizable_exit.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromAlpha="1.0"
+    android:toAlpha="0.0"
+    android:duration="160"
+    android:interpolator="@android:interpolator/fast_out_linear_in"
+    android:zAdjustment="top"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/major_a_b_dot_01_animation.xml b/packages/SystemUI/res/anim/major_a_b_dot_01_animation.xml
new file mode 100644
index 0000000..b5bb4dc
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_a_b_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 3.25,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_a_b_dot_animation.xml b/packages/SystemUI/res/anim/major_a_b_dot_animation.xml
new file mode 100644
index 0000000..6443167
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_a_b_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueTo="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_a_dot_01_animation.xml b/packages/SystemUI/res/anim/major_b_a_dot_01_animation.xml
new file mode 100644
index 0000000..2e0a4fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_a_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 8.0,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_a_dot_animation.xml b/packages/SystemUI/res/anim/major_b_a_dot_animation.xml
new file mode 100644
index 0000000..731c87c
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_a_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyName="pathData"
+        android:valueFrom="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueTo="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_c_dot_01_animation.xml b/packages/SystemUI/res/anim/major_b_c_dot_01_animation.xml
new file mode 100644
index 0000000..e8c2687
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_c_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 8.0,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_b_c_dot_animation.xml b/packages/SystemUI/res/anim/major_b_c_dot_animation.xml
new file mode 100644
index 0000000..731c87c
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_b_c_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyName="pathData"
+        android:valueFrom="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueTo="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_c_b_dot_01_animation.xml b/packages/SystemUI/res/anim/major_c_b_dot_01_animation.xml
new file mode 100644
index 0000000..d0174bc
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_c_b_dot_01_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.75,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/major_c_b_dot_animation.xml b/packages/SystemUI/res/anim/major_c_b_dot_animation.xml
new file mode 100644
index 0000000..6443167
--- /dev/null
+++ b/packages/SystemUI/res/anim/major_c_b_dot_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueTo="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_a_b_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_a_b_dot_02_animation.xml
new file mode 100644
index 0000000..b5bb4dc
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_a_b_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 3.25,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_b_a_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_b_a_dot_02_animation.xml
new file mode 100644
index 0000000..2e0a4fa
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_b_a_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 8.0,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_b_c_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_b_c_dot_02_animation.xml
new file mode 100644
index 0000000..e8c2687
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_b_c_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 8.0,4.0 c 0.79167,0.0 3.95833,0.0 4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/minor_c_b_dot_02_animation.xml b/packages/SystemUI/res/anim/minor_c_b_dot_02_animation.xml
new file mode 100644
index 0000000..d0174bc
--- /dev/null
+++ b/packages/SystemUI/res/anim/minor_c_b_dot_02_animation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyXName="translateX"
+        android:propertyYName="translateY"
+        android:pathData="M 12.75,4.0 c -0.79167,0.0 -3.95833,0.0 -4.75,0.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/recents_from_search_launcher_enter.xml b/packages/SystemUI/res/anim/recents_from_search_launcher_enter.xml
deleted file mode 100644
index 7de4460..0000000
--- a/packages/SystemUI/res/anim/recents_from_search_launcher_enter.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<!-- Recents Activity -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-     android:shareInterpolator="false"
-     android:zAdjustment="normal">
-  <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-         android:fillEnabled="true"
-         android:fillBefore="true" android:fillAfter="true"
-         android:interpolator="@android:interpolator/linear"
-         android:duration="1"/>
-</set>
diff --git a/packages/SystemUI/res/anim/recents_from_search_launcher_exit.xml b/packages/SystemUI/res/anim/recents_from_search_launcher_exit.xml
deleted file mode 100644
index 23cedf8..0000000
--- a/packages/SystemUI/res/anim/recents_from_search_launcher_exit.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<!-- Launcher Activity -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-     android:shareInterpolator="false"
-     android:zAdjustment="top">
-  <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
-         android:fillEnabled="true"
-         android:fillBefore="true" android:fillAfter="true"
-         android:interpolator="@interpolator/recents_from_launcher_exit_interpolator"
-         android:duration="133"/>
-</set>
diff --git a/packages/SystemUI/res/anim/recents_to_search_launcher_enter.xml b/packages/SystemUI/res/anim/recents_to_search_launcher_enter.xml
deleted file mode 100644
index 657b216..0000000
--- a/packages/SystemUI/res/anim/recents_to_search_launcher_enter.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<!-- Launcher Activity -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-     android:shareInterpolator="false"
-     android:zAdjustment="normal">
-  <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-         android:fillEnabled="true"
-         android:fillBefore="true" android:fillAfter="true"
-         android:interpolator="@interpolator/recents_to_launcher_enter_interpolator"
-         android:duration="133"/>
-</set>
diff --git a/packages/SystemUI/res/anim/recents_to_search_launcher_exit.xml b/packages/SystemUI/res/anim/recents_to_search_launcher_exit.xml
deleted file mode 100644
index 5182cab2..0000000
--- a/packages/SystemUI/res/anim/recents_to_search_launcher_exit.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<!-- Recents Activity -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-     android:shareInterpolator="false"
-     android:zAdjustment="top">
-  <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
-         android:fillEnabled="true"
-         android:fillBefore="true" android:fillAfter="true"
-         android:interpolator="@android:interpolator/linear"
-         android:duration="1"/>
-</set>
diff --git a/packages/SystemUI/res/anim/tv_pip_controls_fade_in.xml b/packages/SystemUI/res/anim/tv_pip_controls_fade_in.xml
new file mode 100644
index 0000000..89e4aac
--- /dev/null
+++ b/packages/SystemUI/res/anim/tv_pip_controls_fade_in.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <objectAnimator
+        android:propertyName="translationY"
+        android:valueTo="10dp"
+        android:interpolator="@android:interpolator/linear_out_slow_in"
+        android:duration="@integer/recents_tv_pip_focus_anim_duration" />
+    <objectAnimator
+        android:propertyName="alpha"
+        android:valueTo="1.0"
+        android:interpolator="@android:interpolator/linear_out_slow_in"
+        android:duration="@integer/recents_tv_pip_focus_anim_duration" />
+</set>
diff --git a/packages/SystemUI/res/anim/tv_pip_controls_fade_out.xml b/packages/SystemUI/res/anim/tv_pip_controls_fade_out.xml
new file mode 100644
index 0000000..c73fed6
--- /dev/null
+++ b/packages/SystemUI/res/anim/tv_pip_controls_fade_out.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <objectAnimator
+        android:propertyName="translationY"
+        android:valueTo="0dp"
+        android:interpolator="@android:interpolator/fast_out_linear_in"
+        android:duration="@integer/recents_tv_pip_focus_anim_duration" />
+    <objectAnimator
+        android:propertyName="alpha"
+        android:valueTo="0.0"
+        android:interpolator="@android:interpolator/fast_out_linear_in"
+        android:duration="@integer/recents_tv_pip_focus_anim_duration" />
+</set>
diff --git a/packages/SystemUI/res/drawable/major_a_b.xml b/packages/SystemUI/res/drawable/major_a_b.xml
new file mode 100644
index 0000000..9900048
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_a_b.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="major_a_b"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_01"
+        android:translateX="3.25"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_a_b_animation.xml b/packages/SystemUI/res/drawable/major_a_b_animation.xml
new file mode 100644
index 0000000..74d7544
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_a_b_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/major_a_b" >
+    <target
+        android:name="dot_01"
+        android:animation="@anim/major_a_b_dot_01_animation" />
+    <target
+        android:name="dot"
+        android:animation="@anim/major_a_b_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/major_b_a.xml b/packages/SystemUI/res/drawable/major_b_a.xml
new file mode 100644
index 0000000..3115887
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_a.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="major_b_a"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_01"
+        android:translateX="8"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_b_a_animation.xml b/packages/SystemUI/res/drawable/major_b_a_animation.xml
new file mode 100644
index 0000000..cf446e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_a_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/major_b_a" >
+    <target
+        android:name="dot_01"
+        android:animation="@anim/major_b_a_dot_01_animation" />
+    <target
+        android:name="dot"
+        android:animation="@anim/major_b_a_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/major_b_c.xml b/packages/SystemUI/res/drawable/major_b_c.xml
new file mode 100644
index 0000000..899109e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_c.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="major_b_c"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_01"
+        android:translateX="8"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M -4.75,-2.75 l 9.5,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l -9.5,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_b_c_animation.xml b/packages/SystemUI/res/drawable/major_b_c_animation.xml
new file mode 100644
index 0000000..38e12f4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_b_c_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/major_b_c" >
+    <target
+        android:name="dot_01"
+        android:animation="@anim/major_b_c_dot_01_animation" />
+    <target
+        android:name="dot"
+        android:animation="@anim/major_b_c_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/major_c_b.xml b/packages/SystemUI/res/drawable/major_c_b.xml
new file mode 100644
index 0000000..cc6c615
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_c_b.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="major_c_b"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_01"
+        android:translateX="12.75"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/major_c_b_animation.xml b/packages/SystemUI/res/drawable/major_c_b_animation.xml
new file mode 100644
index 0000000..7f7850d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/major_c_b_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/major_c_b" >
+    <target
+        android:name="dot_01"
+        android:animation="@anim/major_c_b_dot_01_animation" />
+    <target
+        android:name="dot"
+        android:animation="@anim/major_c_b_dot_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_a_b.xml b/packages/SystemUI/res/drawable/minor_a_b.xml
new file mode 100644
index 0000000..c5f5c98
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_a_b.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="minor_a_b"
+    android:alpha="0.3"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_02"
+        android:translateX="3.25"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_a_b_animation.xml b/packages/SystemUI/res/drawable/minor_a_b_animation.xml
new file mode 100644
index 0000000..50e20e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_a_b_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/minor_a_b" >
+    <target
+        android:name="dot_02"
+        android:animation="@anim/minor_a_b_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_a.xml b/packages/SystemUI/res/drawable/minor_b_a.xml
new file mode 100644
index 0000000..3bb08c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_a.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="minor_b_a"
+    android:alpha="0.3"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_02"
+        android:translateX="8"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_a_animation.xml b/packages/SystemUI/res/drawable/minor_b_a_animation.xml
new file mode 100644
index 0000000..460a2f7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_a_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/minor_b_a" >
+    <target
+        android:name="dot_02"
+        android:animation="@anim/minor_b_a_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_c.xml b/packages/SystemUI/res/drawable/minor_b_c.xml
new file mode 100644
index 0000000..95c6463
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_c.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="minor_b_c"
+    android:alpha="0.3"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_02"
+        android:translateX="8"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_b_c_animation.xml b/packages/SystemUI/res/drawable/minor_b_c_animation.xml
new file mode 100644
index 0000000..53b8bd6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_b_c_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/minor_b_c" >
+    <target
+        android:name="dot_02"
+        android:animation="@anim/minor_b_c_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/minor_c_b.xml b/packages/SystemUI/res/drawable/minor_c_b.xml
new file mode 100644
index 0000000..523afaa
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_c_b.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="minor_c_b"
+    android:alpha="0.3"
+    android:width="16dp"
+    android:viewportWidth="16"
+    android:height="8dp"
+    android:viewportHeight="8" >
+    <group
+        android:name="dot_02"
+        android:translateX="12.75"
+        android:translateY="4" >
+        <group
+            android:name="dot_group" >
+            <path
+                android:name="dot"
+                android:fillColor="#FFFFFFFF"
+                android:pathData="M 0.0,-2.75 l 0.0,0.0 c 1.51878306195,0.0 2.75,1.23121693805 2.75,2.75 l 0.0,0.0 c 0.0,1.51878306195 -1.23121693805,2.75 -2.75,2.75 l 0.0,0.0 c -1.51878306195,0.0 -2.75,-1.23121693805 -2.75,-2.75 l 0.0,0.0 c 0.0,-1.51878306195 1.23121693805,-2.75 2.75,-2.75 Z" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/minor_c_b_animation.xml b/packages/SystemUI/res/drawable/minor_c_b_animation.xml
new file mode 100644
index 0000000..bf5e81e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/minor_c_b_animation.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/minor_c_b" >
+    <target
+        android:name="dot_02"
+        android:animation="@anim/minor_c_b_dot_02_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/layout/forced_resizable_activity.xml b/packages/SystemUI/res/layout/forced_resizable_activity.xml
new file mode 100644
index 0000000..df245bc
--- /dev/null
+++ b/packages/SystemUI/res/layout/forced_resizable_activity.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="@string/forced_resizable_info_text"
+        android:textColor="#ffffff"/>
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_customize_panel_content.xml b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
index 75f8fa4..6438564 100644
--- a/packages/SystemUI/res/layout/qs_customize_panel_content.xml
+++ b/packages/SystemUI/res/layout/qs_customize_panel_content.xml
@@ -31,7 +31,8 @@
         android:layout_height="0dp"
         android:layout_weight="1"
         android:scrollIndicators="top"
-        android:scrollbars="vertical" />
+        android:scrollbars="vertical"
+        android:importantForAccessibility="no" />
 
     <View
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/recents_history.xml b/packages/SystemUI/res/layout/recents_history.xml
deleted file mode 100644
index dc2da72..0000000
--- a/packages/SystemUI/res/layout/recents_history.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.systemui.recents.history.RecentsHistoryView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-    <android.support.v7.widget.RecyclerView
-        android:id="@+id/list"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-</com.android.systemui.recents.history.RecentsHistoryView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_history_clear_all_button.xml b/packages/SystemUI/res/layout/recents_history_clear_all_button.xml
deleted file mode 100644
index 05f0979..0000000
--- a/packages/SystemUI/res/layout/recents_history_clear_all_button.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/button"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="start|center_vertical"
-    android:paddingStart="16dp"
-    android:paddingEnd="16dp"
-    android:paddingTop="14dp"
-    android:paddingBottom="14dp"
-    android:drawableStart="@drawable/recents_dismiss_all_history"
-    android:contentDescription="@string/recents_history_clear_all_button_label"
-    android:textSize="14sp"
-    android:textColor="#FFFFFF"
-    android:textAllCaps="true"
-    android:shadowColor="#99000000"
-    android:shadowDx="0"
-    android:shadowDy="2"
-    android:shadowRadius="5"
-    android:fontFamily="sans-serif-medium"
-    android:background="?android:selectableItemBackground"
-    android:visibility="invisible" />
diff --git a/packages/SystemUI/res/layout/recents_history_date.xml b/packages/SystemUI/res/layout/recents_history_date.xml
deleted file mode 100644
index 13c7dbe..0000000
--- a/packages/SystemUI/res/layout/recents_history_date.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingStart="4dp"
-    android:paddingEnd="4dp"
-    android:paddingTop="12dp"
-    android:paddingBottom="12dp"
-    android:gravity="start"
-    android:textSize="14sp"
-    android:textColor="#009688"
-    android:textAllCaps="true"
-    android:fontFamily="sans-serif-medium"
-    android:background="?android:selectableItemBackground"
-    android:alpha="1" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_history_task.xml b/packages/SystemUI/res/layout/recents_history_task.xml
deleted file mode 100644
index e92c24a..0000000
--- a/packages/SystemUI/res/layout/recents_history_task.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="48dp"
-    android:orientation="horizontal"
-    android:clickable="true"
-    android:focusable="true"
-    android:background="?android:selectableItemBackground">
-    <ImageView
-        android:id="@+id/icon"
-        android:layout_width="32dp"
-        android:layout_height="32dp"
-        android:layout_gravity="center"
-        android:layout_marginStart="4dp"
-        android:layout_marginEnd="12dp" />
-    <TextView
-        android:id="@+id/description"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:layout_gravity="end"
-        android:paddingStart="16dp"
-        android:gravity="start|center_vertical"
-        android:textSize="14sp"
-        android:textColor="#FFFFFF"
-        android:fontFamily="sans-serif-medium" />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_on_tv.xml b/packages/SystemUI/res/layout/recents_on_tv.xml
index f0bfebe..0f8c77c 100644
--- a/packages/SystemUI/res/layout/recents_on_tv.xml
+++ b/packages/SystemUI/res/layout/recents_on_tv.xml
@@ -19,8 +19,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clipChildren="false"
-    android:clipToPadding="false"
-    android:layoutDirection="rtl">
+    android:clipToPadding="false">
     <com.android.systemui.recents.tv.views.TaskStackHorizontalGridView
         android:id="@+id/task_list"
         android:layout_width="wrap_content"
@@ -29,20 +28,21 @@
         android:clipToPadding="false"
         android:descendantFocusability="beforeDescendants"
         android:layout_marginTop="@dimen/recents_tv_gird_row_top_margin"
-        android:focusable="true" />
+        android:focusable="true"
+        android:layoutDirection="rtl" />
+
     <View
         android:id="@+id/pip_shade"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:visibility="gone"
-        android:background="#76000000"/>
+        android:background="#76000000" />
 
-    <!-- Placeholder view to handle key events for PIP when it's focused.
-         Size and positions will be adjusted to comply with the PIP bounds -->
-    <View
-        android:id="@+id/pip"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:visibility="gone"
-        android:focusable="true" />
+    <include
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:layout_marginTop="132dp"
+        layout="@layout/tv_pip_controls" />
+
 </com.android.systemui.recents.tv.views.RecentsTvView>
diff --git a/packages/SystemUI/res/layout/recents_history_button.xml b/packages/SystemUI/res/layout/recents_stack_action_button.xml
similarity index 95%
rename from packages/SystemUI/res/layout/recents_history_button.xml
rename to packages/SystemUI/res/layout/recents_stack_action_button.xml
index 538bad1..8783261 100644
--- a/packages/SystemUI/res/layout/recents_history_button.xml
+++ b/packages/SystemUI/res/layout/recents_stack_action_button.xml
@@ -23,7 +23,7 @@
     android:paddingEnd="14dp"
     android:paddingTop="12dp"
     android:paddingBottom="12dp"
-    android:text="@string/recents_history_button_label"
+    android:text="@string/recents_stack_action_button_label"
     android:textSize="14sp"
     android:textColor="#FFFFFF"
     android:textAllCaps="true"
diff --git a/packages/SystemUI/res/layout/recents_task_view_header.xml b/packages/SystemUI/res/layout/recents_task_view_header.xml
index fa65758..2b3c5df 100644
--- a/packages/SystemUI/res/layout/recents_task_view_header.xml
+++ b/packages/SystemUI/res/layout/recents_task_view_header.xml
@@ -14,28 +14,28 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+<!-- The layouts params are calculated in TaskViewHeader.java -->
 <com.android.systemui.recents.views.TaskViewHeader
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/task_view_bar"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/recents_task_bar_height"
+    android:layout_height="wrap_content"
     android:layout_gravity="top|center_horizontal">
     <com.android.systemui.recents.views.FixedSizeImageView
         android:id="@+id/icon"
         android:contentDescription="@string/recents_app_info_button_label"
-        android:layout_width="@dimen/recents_task_view_header_icon_width"
-        android:layout_height="@dimen/recents_task_view_header_icon_height"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|start"
         android:paddingTop="8dp"
         android:paddingBottom="8dp"
-        android:paddingStart="12dp"
-        android:paddingEnd="16dp" />
+        android:paddingStart="16dp"
+        android:paddingEnd="12dp" />
     <LinearLayout
+        android:id="@+id/title_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|start"
-        android:layout_marginStart="56dp"
-        android:layout_marginEnd="56dp"
         android:orientation="vertical">
         <TextView
             android:id="@+id/title"
@@ -67,21 +67,20 @@
     </LinearLayout>
     <com.android.systemui.recents.views.FixedSizeImageView
         android:id="@+id/move_task"
-        android:layout_width="@dimen/recents_task_view_header_button_width"
-        android:layout_height="@dimen/recents_task_view_header_button_height"
-        android:layout_marginEnd="@dimen/recents_task_view_header_button_width"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|end"
-        android:padding="13dp"
+        android:padding="@dimen/recents_task_view_header_button_padding"
         android:src="@drawable/star"
         android:background="?android:selectableItemBackground"
         android:alpha="0"
         android:visibility="gone" />
     <com.android.systemui.recents.views.FixedSizeImageView
         android:id="@+id/dismiss_task"
-        android:layout_width="@dimen/recents_task_view_header_button_width"
-        android:layout_height="@dimen/recents_task_view_header_button_height"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|end"
-        android:padding="13dp"
+        android:padding="@dimen/recents_task_view_header_button_padding"
         android:src="@drawable/recents_dismiss_light"
         android:background="?android:selectableItemBackground"
         android:alpha="0"
diff --git a/packages/SystemUI/res/layout/recents_task_view_header_overlay.xml b/packages/SystemUI/res/layout/recents_task_view_header_overlay.xml
index 1becdab..cf09b1d 100644
--- a/packages/SystemUI/res/layout/recents_task_view_header_overlay.xml
+++ b/packages/SystemUI/res/layout/recents_task_view_header_overlay.xml
@@ -13,6 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+<!-- The layouts params are calculated in TaskViewHeader.java -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
@@ -20,20 +21,18 @@
     <com.android.systemui.recents.views.FixedSizeImageView
         android:id="@+id/app_icon"
         android:contentDescription="@string/recents_app_info_button_label"
-        android:layout_width="@dimen/recents_task_view_header_icon_width"
-        android:layout_height="@dimen/recents_task_view_header_icon_height"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|start"
         android:paddingTop="8dp"
         android:paddingBottom="8dp"
-        android:paddingStart="12dp"
-        android:paddingEnd="16dp" />
+        android:paddingStart="16dp"
+        android:paddingEnd="12dp" />
     <TextView
         android:id="@+id/app_title"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|start"
-        android:layout_marginStart="56dp"
-        android:layout_marginEnd="112dp"
         android:textSize="16sp"
         android:textColor="#ffffffff"
         android:text="@string/recents_empty_message"
@@ -44,10 +43,10 @@
         android:fadingEdge="horizontal" />
     <com.android.systemui.recents.views.FixedSizeImageView
         android:id="@+id/app_info"
-        android:layout_width="@dimen/recents_task_view_header_button_width"
-        android:layout_height="@dimen/recents_task_bar_height"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|end"
-        android:padding="13dp"
+        android:padding="@dimen/recents_task_view_header_button_padding"
         android:background="?android:selectableItemBackground"
         android:src="@drawable/recents_info_light" />
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/tv_pip_controls.xml b/packages/SystemUI/res/layout/tv_pip_controls.xml
new file mode 100644
index 0000000..2e0c9e7
--- /dev/null
+++ b/packages/SystemUI/res/layout/tv_pip_controls.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.systemui.tv.pip.PipControlsView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/pip_controls"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:orientation="horizontal">
+
+    <LinearLayout
+        android:layout_width="100dp"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:gravity="center">
+
+        <ImageView android:id="@+id/full_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:focusable="true"
+            android:src="@drawable/tv_pip_full_button" />
+
+        <TextView android:id="@+id/full_desc"
+            android:layout_width="100dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="3dp"
+            android:gravity="center"
+            android:visibility="invisible"
+            android:text="@string/pip_fullscreen"
+            android:fontFamily="sans-serif"
+            android:textSize="12sp"
+            android:textColor="#EEEEEE" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="100dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="-50dp"
+        android:orientation="vertical"
+        android:gravity="center">
+
+        <ImageView android:id="@+id/close_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:focusable="true"
+            android:src="@drawable/tv_pip_close_button" />
+
+        <TextView android:id="@+id/close_desc"
+            android:layout_width="100dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="3dp"
+            android:gravity="center"
+            android:visibility="invisible"
+            android:text="@string/pip_close"
+            android:fontFamily="sans-serif"
+            android:textSize="12sp"
+            android:textColor="#EEEEEE" />
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/play_pause"
+        android:layout_width="100dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="-50dp"
+        android:orientation="vertical"
+        android:gravity="center" >
+
+        <ImageView android:id="@+id/play_pause_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:focusable="true"
+            android:src="@drawable/tv_pip_pause_button" />
+
+        <TextView android:id="@+id/play_pause_desc"
+            android:layout_width="100dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="3dp"
+            android:gravity="center"
+            android:visibility="invisible"
+            android:text="@string/pip_pause"
+            android:fontFamily="sans-serif"
+            android:textSize="12sp"
+            android:textColor="#EEEEEE" />
+    </LinearLayout>
+</com.android.systemui.tv.pip.PipControlsView>
diff --git a/packages/SystemUI/res/layout/tv_pip_menu.xml b/packages/SystemUI/res/layout/tv_pip_menu.xml
index 1fec49e..c2c83ff 100644
--- a/packages/SystemUI/res/layout/tv_pip_menu.xml
+++ b/packages/SystemUI/res/layout/tv_pip_menu.xml
@@ -26,85 +26,7 @@
     android:gravity="top|center_horizontal"
     android:clipChildren="false">
 
-    <LinearLayout
-        android:layout_width="34dp"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="3dp"
-        android:orientation="vertical"
-        android:gravity="center"
-        android:clipChildren="false">
-
-        <ImageView android:id="@+id/full_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:focusable="true"
-            android:src="@drawable/tv_pip_full_button" />
-
-        <TextView android:id="@+id/full_desc"
-            android:layout_width="100dp"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="3dp"
-            android:gravity="center"
-            android:visibility="invisible"
-            android:text="@string/pip_fullscreen"
-            android:fontFamily="sans-serif"
-            android:textSize="12sp"
-            android:textColor="#EEEEEE"
-            android:clipChildren="false" />
-    </LinearLayout>
-
-    <LinearLayout android:id="@+id/play_pause"
-        android:layout_width="34dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="3dp"
-        android:layout_marginEnd="3dp"
-        android:orientation="vertical"
-        android:gravity="center"
-        android:clipChildren="false">
-
-        <ImageView android:id="@+id/play_pause_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:focusable="true"
-            android:src="@drawable/tv_pip_pause_button" />
-
-        <TextView android:id="@+id/play_pause_desc"
-            android:layout_width="100dp"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="3dp"
-            android:gravity="center"
-            android:visibility="invisible"
-            android:text="@string/pip_pause"
-            android:fontFamily="sans-serif"
-            android:textSize="12sp"
-            android:textColor="#EEEEEE"
-            android:clipChildren="false" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="34dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="3dp"
-        android:orientation="vertical"
-        android:gravity="center"
-        android:clipChildren="false">
-
-        <ImageView android:id="@+id/close_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:focusable="true"
-            android:src="@drawable/tv_pip_close_button" />
-
-        <TextView android:id="@+id/close_desc"
-            android:layout_width="100dp"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="3dp"
-            android:gravity="center"
-            android:visibility="invisible"
-            android:text="@string/pip_close"
-            android:fontFamily="sans-serif"
-            android:textSize="12sp"
-            android:textColor="#EEEEEE"
-            android:clipChildren="false" />
-    </LinearLayout>
+    <include
+        layout="@layout/tv_pip_controls"
+        android:clipChildren="false" />
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/tv_pip_overlay.xml b/packages/SystemUI/res/layout/tv_pip_overlay.xml
index 1ba423b..c5c7e84 100644
--- a/packages/SystemUI/res/layout/tv_pip_overlay.xml
+++ b/packages/SystemUI/res/layout/tv_pip_overlay.xml
@@ -46,16 +46,17 @@
         android:layout_centerHorizontal="true"
         android:orientation="horizontal">
         <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="19dp"
+            android:layout_height="19dp"
             android:src="@drawable/ic_fullscreen_white_24dp" />
         <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_pause_white_24dp" />
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="19dp"
+            android:layout_height="19dp"
             android:src="@drawable/ic_close_white" />
+        <ImageView
+            android:id="@+id/guide_button_play_pause"
+            android:layout_width="19dp"
+            android:layout_height="19dp"
+            android:src="@drawable/ic_pause_white_24dp" />
     </LinearLayout>
 </RelativeLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index d897956..5e6c5f7 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Liggingversoeke aktief"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Kennisgewingsinstellings"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-instellings"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Die skerm sal outomaties draai."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kon nie <xliff:g id="APP">%s</xliff:g> begin nie."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is in veiligmodus gedeaktiveer."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Geskiedenis"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vee uit"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vee alles uit"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Hierdie program steun nie veelvuldige vensters nie"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Program steun nie veelvuldige vensters nie"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Verdeel horisontaal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Wys boaan die kennisgewingslys, verskyn vlugtig op die skerm en laat klank toe"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Meer instellings"</string>
     <string name="notification_done" msgid="5279426047273930175">"Klaar"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>-kennisgewingkontroles"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Kleur en voorkoms"</string>
     <string name="night_mode" msgid="3540405868248625488">"Nagmodus"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibreer skerm"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterybespaarder is nie beskikbaar wanneer gelaai word nie"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterybespaarder"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Verminder werkverrigting en agtergronddata"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Knoppie <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Op"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Af"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Links"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Regs"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Middel"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Spasie"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Syferpaneel <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Stelsel"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Tuis"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Onlangs"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Skuif op"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Skuif links"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Skuif regs"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml
index 391bf7d..0ed4860 100644
--- a/packages/SystemUI/res/values-af/strings_tv.xml
+++ b/packages/SystemUI/res/values-af/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Hou "<b>"TUIS"</b>" om PIP te beheer"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Druk en hou die TUIS-knoppie om PIP te beheer"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Het dit"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Maak toe"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4286af0..3537b97 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"በ GPS የተዘጋጀ ሥፍራ"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"የአካባቢ ጥያቄዎች ነቅተዋል"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"የማሳወቂያ ቅንብሮች"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"የ<xliff:g id="APP_NAME">%s</xliff:g> ቅንብሮች"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ማያ ገጽ በራስ ሰር ይዞራል።"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ን መጀመር አልተቻለም።"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> በጥንቃቄ ሁነታ ውስጥ ታግዷል።"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ታሪክ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ጥረግ"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ሁሉንም አጽዳ"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ይህ መተግበሪያ ብዝሃ-መስኮትን አይደግፍም"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"መተግበሪያው ብዝሃ-መስኮትን አይደግፍም"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"አግድም ክፈል"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"በማሳወቂያዎች ዝርዝር አናት ላይ አሳይ፣ ወደ ማያ ገጹ አሳይና ድምፅ ፍቀድ"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"ተጨማሪ ቅንብሮች"</string>
     <string name="notification_done" msgid="5279426047273930175">"ተከናውኗል"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> ማሳወቂያ ቁጥጥሮች"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"ቀለም እና መልክ"</string>
     <string name="night_mode" msgid="3540405868248625488">"የሌሊት ሁነታ"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ማሳያን ይለኩ"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ኃይል በሚሞላበት ጊዜ ባትሪ ቆጣቢ አይገኝም"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ባትሪ ቆጣቢ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"አፈጻጸምን እና የጀርባ ውሂብን ይቀንሳል"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"አዝራር <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"መነሻ"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"ተመለስ"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ላይ"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ወደታች"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ግራ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ቀኝ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"መሃል"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"ትር"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"ክፍተት"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"አስገባ"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"የኋሊት መደምሰሻ"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"አጫውት/ለአፍታ አቁም"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"አቁም"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"ቀጣይ"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ቀዳሚ"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ወደኋላ አጠንጥን"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"በፍጥነት አሳልፍ"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"ገጽ ወደ ላይ"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"ገጽ ወደ ታች"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ሰርዝ"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"መነሻ"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"መጨረሻ"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"አስገባ"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"የቁጥር ሰሌዳ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ሥርዓት"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"መነሻ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"የቅርብ ጊዜዎቹ"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ወደ ላይ ሂድ"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ወደ ግራ ሂድ"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ወደ ቀኝ ሂድ"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index 19e27ca..9df1916 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIPን ለመቆጣጠር "<b>"መነሻ"</b>"ን ይያዙ"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIPን ለመቆጣጠር የመነሻ አዝራሩን ተጭነው ይያዙ"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"ገባኝ"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"አሰናብት"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5d859ac..1b05192 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -240,8 +240,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"‏تم تعيين الموقع بواسطة GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"طلبات الموقع نشطة"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"و<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"إعدادات الإشعارات"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"إعدادات <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"سيتم تدوير الشاشة تلقائيًا."</string>
@@ -314,8 +313,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"تعذر بدء <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"تم تعطيل <xliff:g id="APP">%s</xliff:g> في الوضع الآمن."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"السجلّ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"محو"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"مسح الكل"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"لا يتيح هذا التطبيق النوافذ المتعددة."</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"لا يتيح التطبيق النوافذ المتعددة."</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسيم أفقي"</string>
@@ -484,8 +482,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"عرض هذا الإشعار بأعلى قائمة الإشعارات وعرضه بسرعة على الشاشة مع السماح بإصدار تنبيه صوتي"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"المزيد من الإعدادات"</string>
     <string name="notification_done" msgid="5279426047273930175">"تم"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"عناصر التحكم في إشعارات <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"اللون والمظهر"</string>
     <string name="night_mode" msgid="3540405868248625488">"الوضع الليلي"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"معايرة الشاشة"</string>
@@ -505,6 +502,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"وضع توفير شحن البطارية غير متاح أثناء الشحن."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"توفير شحن البطارية"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"لخفض مستوى الأداء وبيانات الخلفية"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"الزر <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"أعلى"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"أسفل"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"يسار"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"يمين"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"وسط"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"مسافة"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"تشغيل / إيقاف مؤقت"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"إيقاف"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"التالي"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"السابق"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"إرجاع"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"تقديم سريع"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"الرئيسية"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"لوحة الأرقام <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"النظام"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"الشاشة الرئيسية"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"الأحدث"</string>
@@ -563,4 +586,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"نقل لأعلى"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"نقل لليسار"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"نقل لليمين"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"يمكن ألا يعمل التطبيق مع وضع النوافذ المتعددة."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml
index db91b69..e6fbffc 100644
--- a/packages/SystemUI/res/values-ar/strings_tv.xml
+++ b/packages/SystemUI/res/values-ar/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"‏اضغط "<b>"الرئيسية"</b>" للتحكم في PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"‏اضغط مع الاستمرار على زر الشاشة الرئيسية للتحكم في PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"حسنًا"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"رفض"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index ad106f4..bd7572f 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Yer GPS tərəfindən müəyyən edildi"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Məkan sorğuları arxivi"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Bütün bildirişləri sil."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildiriş ayarları"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ayarları"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik döndəriləcək."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"axtarış"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlana bilmir."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> güvənli rejimdə deaktiv edildi."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Tarixçə"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Təmizləyin"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hamısını silin"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Bu tətbiq çoxsaylı pəncərəni dəstəkləmir"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Bu tətbiq çoxsaylı pəncərəni dəstəkləyir"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Üfüqi Böl"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Bildirişlər siyahısında yuxarıda göstərin, ekrana nəzər salın və səsə icazə verin"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Daha çox ayar"</string>
     <string name="notification_done" msgid="5279426047273930175">"Hazırdır"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> bildiriş nəzarəti"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Rəng və görünüş"</string>
     <string name="night_mode" msgid="3540405868248625488">"Gecə rejimi"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Ekranı kalibrləyin"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Enerji Qənaəti doldurulma zamanı əlçatan deyil"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Enerji Qənaəti"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı azaldır və arxa fon datasını məhdudlaşdırır"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Düymə <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Əsas səhifə"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Geri"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Yuxarı"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Aşağı"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Sol"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Sağ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Mərkəz"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Boşluq"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Daxil olun"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Gerisil"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Oxut/Durdur"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Dayandırın"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Növbəti"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Öncəki"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Geri ötürmə"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"İrəli Ötürmə"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Yuxarı Səhifə"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Aşağı Səhifə"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Silin"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Əsas səhifə"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Son"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Daxil edin"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Nömrələr"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Rəqəmli düymələr <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Əsas səhifə"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Sonuncular"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Yuxarıya keçin"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sola köçürün"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sağa köçürün"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Tətbiq çoxsaylı pəncərə ilə işləməyə bilər."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
index a7a6c5d..63fc9fd 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP idarı etmək üçün "<b>"Əsas səhifəni"</b>" tutub saxlayın"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PİP nəzarət etmək üçün ƏSAS EKRAN düyməni basıb saxlayın"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Rədd edin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index edec332..4935d99 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -237,8 +237,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju je podesio GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Ima aktivnih zahteva za lokaciju"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Obriši sva obaveštenja."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"i još <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Podešavanja obaveštenja"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Podešavanja za <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran će se automatski rotirati."</string>
@@ -311,8 +310,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Pokretanje aplikacije <xliff:g id="APP">%s</xliff:g> nije uspelo."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je onemogućena u bezbednom režimu."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Istorija"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Obriši"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ova aplikacija ne podržava režim sa više prozora"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podržava režim sa više prozora"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podeli horizontalno"</string>
@@ -481,8 +479,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Prikazuju se u vrhu liste obaveštenja, nakratko se prikazuju na ekranu i emituju zvuk"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Još podešavanja"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrole obaveštenja za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Boja i izgled"</string>
     <string name="night_mode" msgid="3540405868248625488">"Noćni režim"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibrišite ekran"</string>
@@ -502,6 +499,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije nije dostupna tokom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje performanse i pozadinske podatke"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Taster Početna"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Taster Nazad"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Taster sa strelicom nagore"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Taster sa strelicom nadole"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Taster sa strelicom nalevo"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Taster sa strelicom nadesno"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Taster sa centralnom strelicom"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Taster za razmak"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Taster za brisanje unazad"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Taster za reprodukciju/pauziranje"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Taster za zaustavljanje"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Taster Sledeća"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Taster Prethodna"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Taster za premotavanje unazad"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Taster za premotavanje unapred"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Taster za stranicu nagore"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Taster za stranicu nadole"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Taster za brisanje"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Taster Početna"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Taster za kraj"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Taster za umetanje"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Taster <xliff:g id="NAME">%1$s</xliff:g> na numeričkoj tastaturi"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni sadržaj"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pomeri nagore"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pomeri ulevo"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pomeri udesno"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index a285627..d026d2c 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109"><b>"POČETNI EKRAN"</b>" kont. PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Pritisnite i zadržite dugme POČETNI EKRAN da biste kontrolisali PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Važi"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be-rBY/strings.xml b/packages/SystemUI/res/values-be-rBY/strings.xml
index e5771d70..9a3fc33 100644
--- a/packages/SystemUI/res/values-be-rBY/strings.xml
+++ b/packages/SystemUI/res/values-be-rBY/strings.xml
@@ -240,8 +240,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Месца задана праз GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Ёсць актыўныя запыты пра месцазнаходжанне"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Выдалiць усе апавяшчэннi."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Налады апавяшчэнняў"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Налады <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран паварочваецца аўтаматычна."</string>
@@ -314,8 +313,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не атрымалася запусціць <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> адключана ў бяспечным рэжыме."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Гісторыя"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ачысціць"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ачысціць усё"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Гэта праграма не падтрымлівае функцыю некалькіх вокнаў"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Праграма не падтрымлівае функцыю некалькіх вокнаў"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Падзяліць гарызантальна"</string>
@@ -484,8 +482,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Паказваць уверсе спіса апавяшчэнняў, хутка паказаць на экране і дазволіць прайграванне гуку"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Дадатковыя налады"</string>
     <string name="notification_done" msgid="5279426047273930175">"Гатова"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Элементы кантролю апавяшчэнняў <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Колер і выгляд"</string>
     <string name="night_mode" msgid="3540405868248625488">"Начны рэжым"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Каліброўка дысплэя"</string>
@@ -505,6 +502,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Эканомія зараду акумулятара недаступная падчас зарадкі"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Эканомія зараду"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Памяншае прадукцыйнасць і фонавую перадачу даных"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Уверх"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Уніз"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Улева"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Управа"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Цэнтр"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Прабел"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Прайграванне/Паўза"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Спыніць"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Наступны"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Папярэдні"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Перамотка назад"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Перамотка наперад"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Лічбавая клавіятура: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Сістэмныя"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Галоўная"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Апошнія"</string>
@@ -564,4 +587,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Перамясціць уверх"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Перамясціць улева"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Перамясціць управа"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-be-rBY/strings_tv.xml b/packages/SystemUI/res/values-be-rBY/strings_tv.xml
index 1c93d24..6138155 100644
--- a/packages/SystemUI/res/values-be-rBY/strings_tv.xml
+++ b/packages/SystemUI/res/values-be-rBY/strings_tv.xml
@@ -29,6 +29,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Утрым. "<b>"HOME"</b>" для кір. PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Націсніце і ўтрымлівайце кнопку HOME для кіравання PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Зразумела"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Адхіліць"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6c65f9f..17e9f690 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Активни заявки за местоположение"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Настройки за известия"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Настройки за <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранът ще се завърта автоматично."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не можа да стартира."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Приложението <xliff:g id="APP">%s</xliff:g> е деактивирано в безопасния режим."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"История"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Изчистване"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Изчистване на всичко"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Това приложение не поддържа няколко прозореца"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Приложението не поддържа няколко прозореца"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хоризонтално разделяне"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Показване най-горе в списъка с известия, както и на екрана и разрешаване на звуков сигнал"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Още настройки"</string>
     <string name="notification_done" msgid="5279426047273930175">"Готово"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Контроли за известията от <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Цвят и облик"</string>
     <string name="night_mode" msgid="3540405868248625488">"Нощен режим"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Калибриране на дисплея"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режимът за запазване на батерията не е налице при зареждане"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим за запазване на батерията"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Намалява ефективността и данните на заден план"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Бутон „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Начало"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Нагоре"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Надолу"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Наляво"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Надясно"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Център"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Интервал"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Пускане/пауза"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Спиране"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Напред"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Назад"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Превъртане назад"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Превъртане напред"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Страница нагоре"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Страница надолу"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Изтриване"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Цифрова клавиатура – <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Системни"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Начало"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Скорошни"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Преместване нагоре"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Преместване наляво"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Преместване надясно"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Приложението може да не работи в режим за няколко прозореца"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
index 9926ef8..38e251b 100644
--- a/packages/SystemUI/res/values-bg/strings_tv.xml
+++ b/packages/SystemUI/res/values-bg/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Контр. на PIP: Задр. "<b>"HOME"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"За контролиране на PIP натиснете и задръжте бутона „HOME“"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрах"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Отхвърляне"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 446d4af..068e1c1 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS এর দ্বারা সেট করা অবস্থান"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"অবস্থান অনুরোধ সক্রিয় রয়েছে"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"সমস্ত বিজ্ঞপ্তি সাফ করুন৷"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>টি"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"বিজ্ঞপ্তির সেটিংস"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> সেটিংস"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"স্ক্রীন স্বয়ংক্রিয়ভাবে ঘুরে যাবে৷"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"অনুসন্ধান"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> শুরু করা যায়নি৷"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"নিরাপদ মোডে <xliff:g id="APP">%s</xliff:g> অক্ষম করা হয়েছে৷"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ইতিহাস"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"সাফ করুন"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"সবকিছু সাফ করুন"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"এই অ্যাপ্লিকেশানটি মাল্টি-উইন্ডো সমর্থন করে না"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"অ্যাপ্লিকেশানগুলি মাল্টি-উইন্ডো সমর্থন করে না"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"অনুভূমিক স্প্লিট"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"বিজ্ঞপ্তি তালিকার শীর্ষে দেখানো হয় এবং স্ক্রীনের উপরে প্রদর্শিত এবং শব্দ করার মঞ্জুরি দেয়"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"আরো সেটিংস"</string>
     <string name="notification_done" msgid="5279426047273930175">"সম্পন্ন"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> বিজ্ঞপ্তির নিয়ন্ত্রণগুলি"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"রঙ এবং চেহারা"</string>
     <string name="night_mode" msgid="3540405868248625488">"রাতের মোড"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"প্রদর্শন ক্যালিব্রেট করুন"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"চার্জ করার সময় ব্যাটারি সেভার উপলব্ধ নয়"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ব্যাটারি সেভার"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"কার্য-সম্পাদনা ও পশ্চাদপট ডেটাকে কমিয়ে দেয়"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> বোতাম"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"হোম"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"ফিরুন"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"উপরে"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"নীচে"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"বাম"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ডান"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"কেন্দ্র"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"ট্যাব"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"স্পেস"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"এন্টার"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"ব্যাকস্পেস"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"প্লে/বিরতি"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"থামান"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"পরবর্তী"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"পূর্ববর্তী"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"পেছনের দিকে যান"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"দ্রুত ফরওয়ার্ড"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"পেজ আপ"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"পেজ ডাউন"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"মুছুন"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"হোম"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"শেষ"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"ঢোকান"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"সংখ্যা লক"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"সংখ্যাপ্যাড <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"সিস্টেম"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"হোম"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"সাম্প্রতিকগুলি"</string>
@@ -544,8 +567,8 @@
     <string name="qs_edit" msgid="2232596095725105230">"সম্পাদনা করুন"</string>
     <string name="tuner_time" msgid="6572217313285536011">"সময়"</string>
   <string-array name="clock_options">
-    <item msgid="5965318737560463480">"ঘন্টা, মিনিট, এবং সেকেন্ড দেখান"</item>
-    <item msgid="1427801730816895300">"ঘন্টা এবং মিনিট দেখান (ডিফল্ট)"</item>
+    <item msgid="5965318737560463480">"ঘণ্টা, মিনিট, এবং সেকেন্ড দেখান"</item>
+    <item msgid="1427801730816895300">"ঘণ্টা এবং মিনিট দেখান (ডিফল্ট)"</item>
     <item msgid="3830170141562534721">"এই আইকনটি দেখাবেন না"</item>
   </string-array>
   <string-array name="battery_options">
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"উপরে সরান"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"বাঁয়ে সরান"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ডানে সরান"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings_tv.xml b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
index cbed4a1..6fa2d5b 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP নিয়ন্ত্রণ করতে "<b>"হোম"</b>" কী ধরে রাখুন"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP নিয়ন্ত্রণ করতে HOME বোতামটিকে টিপুন ও ধরে থাকুন"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"বুঝেছি"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"খারিজ করুন"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index 024bf70..728c874 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -237,8 +237,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija utvrđena GPS signalom"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Aktiviran je zahtjev za lokaciju"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Uklanjanje svih obavještenja."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Postavke obavještenja"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Postavke aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran će se automatski rotirati."</string>
@@ -311,8 +310,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraga"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> je onemogućena u sigurnom načinu rada."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historija"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Obriši"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ova aplikacija ne podržava rad sa više prozora"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podržava rad sa više prozora"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podjela po horizontali"</string>
@@ -481,8 +479,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Prikaži na vrhu liste obavještenja, kratko prikaži na ekranu i dozvoli zvuk"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Više postavki"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrole <xliff:g id="APP_NAME">%1$s</xliff:g> obavještenja"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Boja i izgled"</string>
     <string name="night_mode" msgid="3540405868248625488">"Noćni način rada"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibracija zaslona"</string>
@@ -502,6 +499,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije je isključena prilikom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ograničava rad i prijenos podataka u pozadini"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Dugme <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Tipka za početak"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Nazad"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gore"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dolje"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Lijevo"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Desno"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Sredina"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Razmaknica"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Tipka za novi red"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tipka za brisanje"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Pokreni/pauziraj"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zaustavi"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Sljedeće"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prethodno"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Premotaj"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Ubrzaj"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Tipka Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Tipka Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Tipka za brisanje"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Tipka za početak"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Kraj"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Tipka za umetanje"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Tipka Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numerička tastatura <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početak"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni ekrani"</string>
@@ -561,4 +584,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pomjeri gore"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pomjeri lijevo"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pomjeri desno"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacija možda neće raditi s višestrukim prozorom"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings_tv.xml b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
index 5d20c8c..65c0982 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml
@@ -29,6 +29,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Za kontr. PIP držite "<b>"HOME"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Za kontrolu PIP, pritisnite i držite dugme POČETAK"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Jasno mi je"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 645c84f..352e132 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuració de les notificacions"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuració de l\'aplicació <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No s\'ha pogut iniciar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"En mode segur, l\'aplicació <xliff:g id="APP">%s</xliff:g> està desactivada."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Esborra"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Esborra-ho tot"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Aquesta aplicació no admet el mode multifinestra"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"L\'aplicació no admet el mode multifinestra"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisió horitzontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Les notificacions es mostren al capdamunt de la llista, apareixen a la pantalla i poden emetre sons"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Més opcions"</string>
     <string name="notification_done" msgid="5279426047273930175">"Fet"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Controls de notificació de l\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Color i aparença"</string>
     <string name="night_mode" msgid="3540405868248625488">"Mode nocturn"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibra la pantalla"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"La funció Estalvi de bateria no està disponible durant la càrrega"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Estalvi de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Redueix el rendiment i les dades en segon pla"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botó <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Inici"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Enrere"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Amunt"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Avall"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Esquerra"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Dreta"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Pestanya"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Espai"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Retorn"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retrocés"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reprodueix/Pausa"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Atura"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Següent"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rebobina"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avança ràpidament"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Re Pàg"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Av Pàg"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Suprimeix"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Inici"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Final"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insereix"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloqueig de teclat numèric"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclat numèric <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inici"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recents"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mou amunt"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mou a l\'esquerra"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mou a la dreta"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"És possible que l\'aplicació no funcioni amb el Mode multifinestra"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
index 35482d4..8876664 100644
--- a/packages/SystemUI/res/values-ca/strings_tv.xml
+++ b/packages/SystemUI/res/values-ca/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Prem "<b>"INICI"</b>" per controlar PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Mantén premut el botó INICI per controlar PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"D\'acord"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignora"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 5ce6bd9..ea8ae38 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -311,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikaci <xliff:g id="APP">%s</xliff:g> nelze spustit."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikace <xliff:g id="APP">%s</xliff:g> je v nouzovém režimu zakázána."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historie"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vymazat"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vymazat vše"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Tato aplikace režim v několika oknech nepodporuje"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikace režim v několika oknech nepodporuje"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vodorovné rozdělení"</string>
@@ -501,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Spořič baterie při nabíjení není k dispozici."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Spořič baterie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omezuje výkon a data na pozadí"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tlačítko <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Zpět"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Nahoru"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dolů"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vlevo"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Vpravo"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Střed"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulátor"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Mezerník"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Přehrát/Pozastavit"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zastavit"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Další"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Předchozí"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Přetočit zpět"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Přetočit vpřed"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> na numerické klávesnici"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systém"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Plocha"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Poslední"</string>
@@ -559,4 +584,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Přesunout nahoru"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Přesunout vlevo"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Přesunout vpravo"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 0538bdb..b6c2b73 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Aktive placeringsanmodninger"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle underretninger."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> mere"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Underretningsindstillinger"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Indstillinger for <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er deaktiveret i sikker tilstand."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historik"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ryd"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ryd alle"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Denne app understøtter ikke flere vinduer"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Appen understøtter ikke flere vinduer"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Opdel vandret"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Vis øverst på listen over underretninger, vis på skærmen, og tillad lyd"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Flere indstillinger"</string>
     <string name="notification_done" msgid="5279426047273930175">"Færdig"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrolelementer til underretninger for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Farve og udseende"</string>
     <string name="night_mode" msgid="3540405868248625488">"Nattilstand"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibrer skærmen"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparefunktionen er ikke tilgængelig under opladning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparefunktion"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reducerer ydeevne og baggrundsdata"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g>-knap"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Tilbage"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Op"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ned"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Venstre"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Højre"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Midtertast"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulatortast"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Mellemrumstast"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tilbagetast"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Afspil/pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Næste"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Forrige"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spol tilbage"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Spol frem"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numerisk tastatur <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Start"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Seneste"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Flyt op"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Flyt til venstre"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Flyt til højre"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml
index 51b8582..45bba75 100644
--- a/packages/SystemUI/res/values-da/strings_tv.xml
+++ b/packages/SystemUI/res/values-da/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Hold "<b>"HOME"</b>" nede for at styre PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Tryk på HOME-knappen, og hold den nede for at styre PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Afvis"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 4cd0316..922939e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Benachrichtigungseinstellungen"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Einstellungen von <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ist im abgesicherten Modus deaktiviert."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Verlauf"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Löschen"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Alle löschen"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Diese App unterstützt den Mehrfenstermodus nicht"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App unterstützt Mehrfenstermodus nicht"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Geteilte Schaltfläche – horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Ganz oben in der Benachrichtigungsliste anzeigen, auf dem Display einblenden und Ton zulassen"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Weitere Einstellungen"</string>
     <string name="notification_done" msgid="5279426047273930175">"Fertig"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>-Benachrichtigungseinstellungen"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Farbe und Darstellung"</string>
     <string name="night_mode" msgid="3540405868248625488">"Nachtmodus"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Bildschirm kalibrieren"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Der Energiesparmodus ist beim Aufladen nicht verfügbar."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Energiesparmodus"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduzierung der Leistung und Hintergrunddaten"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Taste <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Pos1"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Zurück"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Nach oben"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Nach unten"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Nach links"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Nach rechts"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Zentrieren"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulatortaste"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Leertaste"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Eingabetaste"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Rücktaste"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Wiedergabe/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stopp"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Weiter"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Zurück"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Zurückspulen"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Vorspulen"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Nach oben"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Nach unten"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Entf"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Pos1"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Ende"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Einfg"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Ziffernblock <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startseite"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Letzte"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Nach oben verschieben"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Nach links verschieben"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Nach rechts verschieben"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"App funktioniert im Mehrfenstermodus möglicherweise nicht"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
index f448737..3d9c233 100644
--- a/packages/SystemUI/res/values-de/strings_tv.xml
+++ b/packages/SystemUI/res/values-de/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109"><b>"STARTBILDSCHIRMTASTE"</b>" drücken, um PIP zu steuern"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Halte die Taste für die Startseite gedrückt, um das Bild-in-Bild zu steuern"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Beenden"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 59810c2..7a23ac9 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Ρύθμιση τοποθεσίας με GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Τα αιτήματα τοποθεσίας έχουν ενεργοποιηθεί"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ρυθμίσεις ειδοποιήσεων"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ρυθμίσεις <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Θα γίνεται αυτόματη περιστροφή της οθόνης."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Δεν ήταν δυνατή η εκκίνηση της εφαρμογής <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Η εφαρμογή <xliff:g id="APP">%s</xliff:g> έχει απενεργοποιηθεί στην ασφαλή λειτουργία."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Ιστορικό"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Εκκαθάριση"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Διαγραφή όλων"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Η εφαρμογή αυτή δεν υποστηρίζει τη λειτουργία πολλαπλών παραθύρων"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Η εφαρμογή δεν υποστηρίζει τη λειτουργία πολλαπλών παραθύρων"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Οριζόντιος διαχωρισμός"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Να εμφανίζονται στην κορυφή της λίστας ειδοποιήσεων, να προβάλλονται στην οθόνη και να επιτρέπεται ο ήχος"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Περισσότερες ρυθμίσεις"</string>
     <string name="notification_done" msgid="5279426047273930175">"Τέλος"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Στοιχεία ελέγχου κοινοποίησης <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Χρώμα και εμφάνιση"</string>
     <string name="night_mode" msgid="3540405868248625488">"Νυχτερινή λειτουργία"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Βαθμονόμηση οθόνης"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Η εξοικονόμηση μπαταρίας δεν είναι διαθέσιμη κατά τη διάρκεια της φόρτισης"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Εξοικονόμηση μπαταρίας"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Μειώνει την απόδοση και τα δεδομένα παρασκηνίου"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Κουμπί <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Πίσω"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Πάνω"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Κάτω"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Αριστερά"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Δεξιά"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Κέντρο"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Πλήκτρο διαστήματος"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Αναπαραγωγή/Παύση"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Διακοπή"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Επόμενο"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Προηγούμενο"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Επαναφορά"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Γρήγορη προώθηση"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Προηγούμενη σελίδα"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Επόμενη σελίδα"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Λήξη"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Αριθμητικό πληκτρολόγιο <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Σύστημα"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Αρχική οθόνη"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Πρόσφατα"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Μετακίνηση προς τα επάνω"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Μετακίνηση αριστερά"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Μετακίνηση δεξιά"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Η εφαρμογή ενδέχεται να μη λειτουργεί με τη λειτουργία πολλαπλών παραθύρων"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml
index 355c9b0..c54c7be 100644
--- a/packages/SystemUI/res/values-el/strings_tv.xml
+++ b/packages/SystemUI/res/values-el/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Κρατήστε το πλήκτρο "<b>"HOME"</b>" πατημένο για έλεγχο του PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Πιέστε παρατεταμένα το κουμπί HOME, για να ελέγξετε τη λειτουργία PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Κατάλαβα"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Παράβλεψη"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 9346188..6f4ae7b 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"This app does not support multi-window"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App does not support multi-window"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast-Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Move up"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Move to the left"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Move to the right"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"App may not work with multi-window"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 9346188..6f4ae7b 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"This app does not support multi-window"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App does not support multi-window"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast-Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Move up"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Move to the left"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Move to the right"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"App may not work with multi-window"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 9346188..6f4ae7b 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"This app does not support multi-window"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App does not support multi-window"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast-Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Move up"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Move to the left"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Move to the right"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"App may not work with multi-window"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 45b4020..9106592 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuración de notificaciones"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuración de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
@@ -304,14 +303,13 @@
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Modo de trabajo"</string>
     <string name="recents_empty_message" msgid="808480104164008572">"No hay elementos recientes"</string>
-    <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"Borraste todo"</string>
+    <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"Todo borrado"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Fijar pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No se pudo iniciar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> está inhabilitada en modo seguro."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta app no es compatible con el modo multiventana"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"La app no es compatible con el modo multiventana"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Mostrar en la parte superior de la lista de notificaciones, ver en la pantalla y permitir sonidos"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Más opciones de configuración"</string>
     <string name="notification_done" msgid="5279426047273930175">"Listo"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Controles de notificaciones de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Color y apariencia"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modo nocturno"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrar pantalla"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no está disponible durante la carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y el uso de datos en segundo plano"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Página principal"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Atrás"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Arriba"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Abajo"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Izquierda"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Derecha"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centro"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulación"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Espacio"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Ingresar"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retroceso"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproducir/pausar"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Detener"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Siguiente"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retroceder"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avanzar rápido"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Página anterior"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Página siguiente"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Borrar"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Página principal"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Finalizar"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insertar"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloqueo numérico"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pantalla principal"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover hacia arriba"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover a la izquierda"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover a la derecha"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
index 98ad35b..72ea127 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Mantén presionado "<b>"INICIO"</b>" para controlar PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Mantén presionado el botón INICIO para controlar PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendido"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Descartar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 5c84999..c2f3a3a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -236,7 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
-    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ de <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ajustes de notificaciones"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ajustes de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No se ha podido iniciar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"La aplicación <xliff:g id="APP">%s</xliff:g> se ha inhabilitado en modo seguro."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta aplicación no admite el modo multiventana."</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"La aplicación no admite el modo multiventana"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no disponible mientras se carga el dispositivo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y las conexiones automáticas"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Inicio"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Atrás"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Arriba"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Abajo"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Izquierda"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Derecha"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centro"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulador"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Espacio"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Intro"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tecla de retroceso"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproducir/Pausa"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Detener"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Siguiente"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rebobinar"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rápido"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Retroceder página"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Avanzar página"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supr"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Inicio"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloq Num"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Subir"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover a la izquierda"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover a la derecha"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Es posible que la aplicación no funcione con el modo multiventana"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 423166f..0524d3b 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Rakendust <xliff:g id="APP">%s</xliff:g> ei saanud käivitada."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Rakendus <xliff:g id="APP">%s</xliff:g> on turvarežiimis keelatud."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Ajalugu"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Kustuta"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Kustuta kõik"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"See rakendus ei toeta mitut akent"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Rakendus ei toeta mitut akent"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horisontaalne poolitamine"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akusäästja pole laadimise ajal saadaval"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akusäästja"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vähendab jõudlust ja taustaandmeid"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Nupp <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Avaekraan"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Tagasi"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Üles"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Alla"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vasakule"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Paremale"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Keskele"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulaator"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Tühik"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Sisestusklahv"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tagasilüke"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Esita/peata"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Peata"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Järgmine"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Eelmine"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Keri tagasi"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Keri edasi"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Lehe võrra üles"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Lehe võrra alla"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Kustuta"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Avaekraan"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Lõpp"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Sisesta"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Numbrilukk"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numbriklahvistik <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Süsteem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Avaekraan"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Hiljutised"</string>
@@ -557,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Liigu üles"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Liigu vasakule"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Liigu paremale"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 435e821..2e207c1 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Kokapena GPS bidez ezarri da"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Aplikazioen kokapen-eskaerak aktibo daude"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Garbitu jakinarazpen guztiak."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Jakinarazpen-ezarpenak"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ezarpenak"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Pantaila automatikoki biratuko da."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"bilatu"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ezin izan da hasi <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> desgaituta dago modu seguruan."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Garbitu"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Garbitu guztiak"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Aplikazioak ez du onartzen leiho bat baino gehiago erabiltzea"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikazioak ez du onartzen leiho bat baino gehiago erabiltzea"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Zatitze horizontala"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Erakutsi jakinarazpen hauek zerrendaren goialdean, agerrarazi pantailan eta egin soinua"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Ezarpen gehiago"</string>
     <string name="notification_done" msgid="5279426047273930175">"Eginda"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren jakinarazpenak kontrolatzeko aukerak"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Kolorea eta itxura"</string>
     <string name="night_mode" msgid="3540405868248625488">"Gau modua"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibratu pantaila"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Bateria-aurrezlea ez dago erabilgarri gailua kargatzen ari denean"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Bateria-aurrezlea"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Errendimendua eta atzeko planoko datuen erabilera murrizten ditu"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> botoia"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Hasiera"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Atzera"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gora"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Behera"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Ezkerrera"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Eskuinera"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Erdiratu"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabuladorea"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Zuriunea"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Sartu"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Atzera"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Erreproduzitu/Pausatu"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Gelditu"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Hurrengoa"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Aurrekoa"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Atzeratu"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Aurreratu"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Orria gora"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Orria behera"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ezabatu"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Hasiera"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Amaitu"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Txertatu"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Blok Zenb"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Zenbaki-teklatuko <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Hasierako pantaila"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Azkenak"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Eraman gora"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Eraman ezkerrera"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Eraman eskuinera"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings_tv.xml b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
index f28ec5e..b812143 100644
--- a/packages/SystemUI/res/values-eu-rES/strings_tv.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109"><b>"HASIERA"</b>" PIP kontrolatzeko"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Eduki sakatuta hasierako botoia pantaila txikia kontrolatzeko"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Ados"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Baztertu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index f2e977c..777fd2b 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"‏مکان تنظیم شده توسط GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"درخواست‌های موقعیت مکانی فعال است"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلان‌ها"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"تنظیمات اعلان"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"تنظیمات <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"صفحه به صورت خودکار می‌چرخد."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> شروع نشد."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> در حالت ایمن غیرفعال است."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"سابقه"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"پاک کردن"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"پاک کردن همه"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"این برنامه از چندپنجره پشتیبانی نمی‌کند"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"برنامه از چندپنجره پشتیبانی نمی‌کند"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسیم افقی"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"در بالای فهرست اعلان نشان داده شوند، در صفحه نشان داده شوند و صدادار باشند"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"تنظیمات بیشتر"</string>
     <string name="notification_done" msgid="5279426047273930175">"تمام"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"کنترل‌های اعلان <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"رنگ و ظاهر"</string>
     <string name="night_mode" msgid="3540405868248625488">"حالت شب"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"درجه‌بندی نمایشگر"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"هنگام شارژ شدن، «بهینه‌سازی باتری» در دسترس نیست"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بهینه‌سازی باتری"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"عملکرد و اطلاعات پس‌زمینه را کاهش می‌دهد"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"دکمه <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"ابتدا"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"برگشت"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"بالا"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"پایین"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"چپ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"راست"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"مرکز"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"جهش"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"فاصله"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"ورود"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"پس‌بر"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"پخش/مکث"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"توقف"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"بعدی"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"قبلی"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"عقب بردن"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"جلو بردن سریع"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"صفحه بعدی"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"صفحه قبلی"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"حذف"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"ابتدا"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"انتها"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"درج"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"قفل اعداد"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"صفحه‌کلید عددی <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"سیستم"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"صفحه اصلی"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"موارد اخیر"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"انتقال به بالا"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"انتقال به چپ"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"انتقال به راست"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"برنامه ممکن است با چندپنجره کار نکند"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml
index 5177724..0d028d8 100644
--- a/packages/SystemUI/res/values-fa/strings_tv.xml
+++ b/packages/SystemUI/res/values-fa/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"‏کنترل PIP ‏با نگه‌داشتن "<b>"HOME"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"‏برای کنترل PIP دکمه صفحه اصلی را فشار داده و نگه‌دارید"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"متوجه شدم"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"رد کردن"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 11cb91e..f100d21 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Sijaintipyynnöt aktiiviset"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ilmoitusasetukset"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Asetukset – <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ruutu kääntyy automaattisesti."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"haku"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Sovelluksen <xliff:g id="APP">%s</xliff:g> käynnistäminen epäonnistui."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> on poistettu käytöstä vikasietotilassa."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tyhjennä"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tyhjennä kaikki"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Tämä sovellus ei tue usean ikkunan tilaa."</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Sovellus ei tue usean ikkunan tilaa."</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vaakasuuntainen jako"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Näytä ilmoitukset näytöllä ja ilmoitusluettelon yläosassa ja salli niiden äänet."</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Lisäasetukset"</string>
     <string name="notification_done" msgid="5279426047273930175">"Valmis"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ilmoitusten hallinta"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Väri ja ulkoasu"</string>
     <string name="night_mode" msgid="3540405868248625488">"Yötila"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibroi näyttö"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Virransäästö ei ole käytettävissä latauksen aikana."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Virransäästö"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Rajoittaa suorituskykyä ja taustatiedonsiirtoa."</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Painike <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Takaisin"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Ylös"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Alas"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vasemmalle"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Oikealle"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Keskelle"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Sarkain"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Välilyönti"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Askelpalautin"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Toisto/keskeytys"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Pysäytä"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seuraava"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Edellinen"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Kelaa taaksepäin"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Kelaa eteenpäin"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numeronäppäimistö <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Järjestelmä"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Aloitusnäyttö"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Viimeaikaiset"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Siirrä ylöspäin"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Siirrä vasemmalle"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Siirrä oikealle"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
index 642ed20..9124f67d 100644
--- a/packages/SystemUI/res/values-fi/strings_tv.xml
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP: paina pitkään "<b>"aloituspain"</b>"."</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Hallinnoi PIP-tilaa painamalla ALOITUSNÄYTTÖ-painiketta pitkään."</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Selvä"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Hylkää"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index c647cc9..1bec7fd 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Paramètres de notification"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Paramètres de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> est désactivée en mode sécurisé."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historique"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Effacer"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Effacer tout"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Cette application ne prend pas en charge le mode multifenêtre"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"L\'application ne prend pas en charge le mode multifenêtre"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Afficher en haut de la liste des notifications, afficher sur l\'écran et émettre un son"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Plus de paramètres"</string>
     <string name="notification_done" msgid="5279426047273930175">"Terminé"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Commandes de notification pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Couleur et apparence"</string>
     <string name="night_mode" msgid="3540405868248625488">"Mode Nuit"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrer l\'affichage"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Le mode Économie d\'énergie n\'est pas accessible pendant la charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économie d\'énergie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Réduit les performances et les données en arrière-plan"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Bouton <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Accueil"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Précédent"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Haut"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Bas"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Gauche"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Droite"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centrer"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulation"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Espace"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Entrée"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retour arrière"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Lecture/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Arrêter"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Suivant"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Précédent"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Reculer"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rapide"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page précédente"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page suivante"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supprimer"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Accueil"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insérer"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Verr num"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Pavé numérique <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Système"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Déplacer vers le haut"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Déplacer vers la gauche"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Déplacer vers la droite"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
index 1ae3c5c..597a588 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Maint. enf. "<b>"ACC."</b>" pr gér. mode IDI"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Maintenez enfoncé le bouton ACCUEIL pour gérer le mode IDI."</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Fermer"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7d91f6f..bb22848 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> autres"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Paramètres de notification"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Paramètres de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"L\'application <xliff:g id="APP">%s</xliff:g> est désactivée en mode sécurisé."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historique"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Effacer"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tout effacer"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Application incompatible avec le mode multifenêtre."</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Application incompatible avec le mode multifenêtre"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Afficher en haut de la liste des notifications, afficher sur l\'écran et émettre un son"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Plus de paramètres"</string>
     <string name="notification_done" msgid="5279426047273930175">"Terminé"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Commandes de notification de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Couleur et apparence"</string>
     <string name="night_mode" msgid="3540405868248625488">"Mode Nuit"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrer l\'affichage"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"L\'économiseur de batterie n\'est pas disponible lorsque l\'appareil est en charge."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économiseur de batterie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Limite les performances et les données en arrière-plan."</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Bouton <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Accueil"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Précédent"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Vers le haut"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Vers le bas"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vers la gauche"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Vers la droite"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulation"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Espace"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Entrée"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retour arrière"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Lire ou suspendre la lecture"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Arrêter"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Suivant"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Précédent"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retour arrière"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rapide"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page précédente"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page suivante"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supprimer"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Accueil"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insérer"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Verr Num"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Pavé numérique <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Système"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Déplacer vers le haut"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Déplacer vers la gauche"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Déplacer vers la droite"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml
index 68c4dcb..0478eea 100644
--- a/packages/SystemUI/res/values-fr/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Appui long "<b>"ACCUEIL"</b>" pour contrôler PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Appuyez de manière prolongée sur le bouton ACCUEIL pour contrôler le mode PIP."</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorer"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 1474acf..6d4b7eb 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Localización establecida polo GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de localización activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas as notificacións."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuración das notificacións"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuración de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A pantalla xirará automaticamente."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Non foi posible iniciar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"A aplicación <xliff:g id="APP">%s</xliff:g> está desactivada no modo seguro"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta aplicación non é compatible con varias ventás"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"A aplicación non é compatible con varias ventás"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dividir en horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificacións, amosar na pantalla e permitir que emita son"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Máis opcións"</string>
     <string name="notification_done" msgid="5279426047273930175">"Feito"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Controis de notificacións de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Cor e aspecto"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modo nocturno"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrar pantalla"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A función aforro de batería non está dispoñible durante a carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Aforro de batería"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce o rendemento e os datos en segundo plano"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botón <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Inicio"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Volver"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Arriba"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Abaixo"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Esquerda"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Dereita"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centro"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulador"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Espazo"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Intro"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retroceso"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproducir/Pausar"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Deter"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seguinte"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rebobinar"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avance rápido"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Re Páx"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Av Páx"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Supr"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Inicio"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fin"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Inserir"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloqueo numérico"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Subir"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover á esquerda"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover á dereita"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings_tv.xml b/packages/SystemUI/res/values-gl-rES/strings_tv.xml
index 11d2d4c..d43d8cc 100644
--- a/packages/SystemUI/res/values-gl-rES/strings_tv.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Manter premido "<b>"INICIO"</b>" para controlar PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Mantén premido o botón de INICIO para controlar PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"De acordo"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 7b64214..5b68088 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"શોધ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી શકાયું નથી."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"સુરક્ષિત મોડમાં <xliff:g id="APP">%s</xliff:g> અક્ષમ કરેલ છે."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ઇતિહાસ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"સાફ કરો"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"બધું સાફ કરો"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"આ ઍપ્લિકેશન મલ્ટિ-વિંડોનું સમર્થન કરતી નથી"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ઍપ્લિકેશન મલ્ટિ-વિંડોનું સમર્થન કરતી નથી"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"આડું વિભક્ત કરો"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ચાર્જિંગ દરમિયાન બૅટરી બચતકર્તા ઉપલબ્ધ નથી"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"બૅટરી બચતકર્તા"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"પ્રદર્શન અને પૃષ્ઠભૂમિ ડેટા ઘટાડે છે"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"બટન <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"સિસ્ટમ"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"હોમ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"તાજેતરના"</string>
@@ -557,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ઉપર ખસેડો"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ડાબે ખસેડો"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"જમણે ખસેડો"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 84c073d..44c0dbc 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ नहीं किया जा सका."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> को सुरक्षित-मोड में अक्षम किया गया."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"साफ़ करें"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"यह ऐप्लिकेशन एकाधिक विंडो का समर्थन नहीं करता है"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ऐप्लिकेशन एकाधिक विंडो का समर्थन नहीं करता है"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज रूप से विभाजित करें"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज किए जाने के दौरान बैटरी सेवर उपलब्ध नहीं है"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बैटरी सेवर"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"निष्‍पादन और पृष्ठभूमि डेटा को कम करता है"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"बटन <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ऊपर तीर"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"नीचे तीर"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"बायां तीर"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"दायां तीर"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"मध्य तीर"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टम"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हाल ही के"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ऊपर ले जाएं"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"बाएं ले जाएं"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"दाएं ले जाएं"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"हो सकता है कि ऐप्लिकेशन एकाधिक विंडो के साथ काम ना करे"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e69ad31..c3d6a24 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -237,8 +237,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Zahtjevi za lokaciju aktivni su"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"još <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Postavke obavijesti"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Postavke aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon će se automatski zakrenuti."</string>
@@ -311,8 +310,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> onemogućena je u sigurnom načinu."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Povijest"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Izbriši"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Izbriši sve"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ta aplikacija ne podržava više prozora"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podržava više prozora"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podijeli vodoravno"</string>
@@ -481,8 +479,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Prikaži pri vrhu popisa obavijesti, prikaži na zaslonu i dopusti zvuk"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Više postavki"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrole obavijesti za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Boja i izgled"</string>
     <string name="night_mode" msgid="3540405868248625488">"Noćni način rada"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibriranje zaslona"</string>
@@ -502,6 +499,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Štednja baterije nije dostupna tijekom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Štednja baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje količinu rada i pozadinske podatke"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tipka <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Početak"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Natrag"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gore"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dolje"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Lijevo"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Desno"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Sredina"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Razmaknica"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Unos"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Povratna tipka"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reprodukcija/pauza"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zaustavi"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Sljedeće"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prethodno"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Unatrag"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Brzo naprijed"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Stranica prema gore"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Stranica prema dolje"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Izbriši"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Početak"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Kraj"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Umetni"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Zaključavanje brojčane tipkovnice"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Brojčana tipkovnica <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sustav"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni zaslon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Najnovije"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pomakni prema gore"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pomakni ulijevo"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pomakni udesno"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacija možda neće funkcionirati uz više prozora"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml
index 3d5c8f8..340a613 100644
--- a/packages/SystemUI/res/values-hr/strings_tv.xml
+++ b/packages/SystemUI/res/values-hr/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Držite "<b>"POČETNI"</b>" za PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Pritisnite i zadržite tipku POČETNI ZASLON da biste upravljali slikom u slici"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Shvaćam"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odbaci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index a7d62c3..40fb3e23 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nem lehet elindítani a következőt: <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"A(z) <xliff:g id="APP">%s</xliff:g> csökkentett módban ki van kapcsolva."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Előzmények"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Törlés"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Összes törlése"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ez az alkalmazás nem támogatja a többablakos nézetet"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Az alkalmazás nem támogatja a többablakos nézetet"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Osztott vízszintes"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Az Akkumulátorkímélő módot töltés közben nem lehet használni"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akkumulátorkímélő mód"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Csökkenti a teljesítményt és a háttéradatok használatát"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> gomb"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Kezdőképernyő"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Vissza"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Fel"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Le"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Balra"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Jobbra"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Középre"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Szóköz"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Visszatörlés"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Lejátszás/szünet"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Leállítás"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Következő"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Előző"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Visszatekerés"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Gyors előretekerés"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Kezdőképernyő"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numerikus: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Rendszer"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Otthon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Legutóbbiak"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mozgatás felfelé"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mozgatás balra"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mozgatás jobbra"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Lehet, hogy az alkalmazás nem működik többablakos nézetben"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 79e5268..a2e45e1 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Տեղադրությունը կարգավորվել է GPS-ի կողմից"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Տեղադրության հարցումներն ակտիվ են"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ծանուցման կարգավորումներ"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-ի կարգավորումներ"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Էկրանը ինքնաշխատ կպտտվի:"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"որոնել"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Հնարավոր չէ գործարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> հավելվածը անվտանգ ռեժիմում անջատված է:"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Պատմություն"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Մաքրել"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Մաքրել բոլորը"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Այս հավելվածը չի աջակցում բազմապատուհան ռեժիմը"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Հավելվածը չի աջակցում բազմապատուհան ռեժիմը"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Հորիզոնական տրոհում"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Ցույց տալ ծանուցումների ցանկի վերևում, թռուցիկ ցուցադրել էկրանին և թույլատրել ձայնային ազդանշանը"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Այլ կարգավորումներ"</string>
     <string name="notification_done" msgid="5279426047273930175">"Պատրաստ է"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի ծանուցումների կառավարներ"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Գույնը և արտաքին տեսքը"</string>
     <string name="night_mode" msgid="3540405868248625488">"Գիշերային ռեժիմ"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Չափաբերել էկրանը"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Մարտկոցի տնտեսումը լիցքավորման ժամանակ հասանելի չէ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Մարտկոցի տնտեսում"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Նվազեցնում է ծանրաբեռնվածությունը և ֆոնային տվյալները"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> կոճակ"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Գլխավոր էջ"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Հետ"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Վերև"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ներքև"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Ձախ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Աջ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Կենտրոն"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Բացատ"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Մուտք"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Հետշարժ"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Նվագարկում/դադար"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Դադարեցնել"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Հաջորդը"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Նախորդը"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Հետ անցնել"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Արագ առաջ անցնել"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ջնջել"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Գլխավոր էջ"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Վերջ"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Տեղադրել"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Համակարգ"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Գլխավոր էջ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Վերջինները"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Տեղափոխել վերև"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Տեղափոխել ձախ"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Տեղափոխել աջ"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
index dc4c312..5f9c127 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP-ն կառավարելու համար սեղմած պահեք "<b>"HOME"</b>" կոճակը"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP-ն կառավարելու համար սեղմեք և պահեք HOME կոճակը"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Պարզ է"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Փակել"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3ac5904..cad0e22 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Setelan pemberitahuan"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> setelan"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulai <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> dinonaktifkan dalam mode aman."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Riwayat"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Hapus"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hapus semua"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Aplikasi ini tidak mendukung multijendela"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikasi tidak mendukung multijendela"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Pisahkan Horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Tampilkan di bagian atas daftar notifikasi, muncul di layar, dan izinkan suara"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Setelan lainnya"</string>
     <string name="notification_done" msgid="5279426047273930175">"Selesai"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrol notifikasi <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Warna dan tampilan"</string>
     <string name="night_mode" msgid="3540405868248625488">"Mode malam"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibrasi layar"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penghemat Baterai tidak tersedia selama pengisian daya"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penghemat Baterai"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangi performa dan data latar belakang"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tombol <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Layar Utama"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaru"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Naikkan"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pindahkan ke kiri"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pindahkan ke kanan"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikasi mungkin tidak berfungsi dengan multi-jendela"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml
index 8e3a5e0..7de1a78 100644
--- a/packages/SystemUI/res/values-in/strings_tv.xml
+++ b/packages/SystemUI/res/values-in/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Tahan "<b>"LAYAR UTAMA"</b>" untuk mengontrol PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Tekan dan tahan tombol LAYAR UTAMA untuk mengontrol PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Mengerti"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Tutup"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index c063c73..f609800 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Staðsetning valin með GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Staðsetningarbeiðnir virkar"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Hreinsa allar tilkynningar."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Tilkynningastillingar"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Stillingar fyrir <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjárinn snýst sjálfkrafa."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"leita"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ekki var hægt að ræsa <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Slökkt er á <xliff:g id="APP">%s</xliff:g> í öruggri stillingu."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Ferill"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Hreinsa"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hreinsa allt"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Þetta forrit styður ekki marga glugga"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Forritið styður ekki marga glugga"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Lárétt skipting"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Sýna efst á tilkynningalistanum, birta á skjánum og leyfa hljóð"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Fleiri stillingar"</string>
     <string name="notification_done" msgid="5279426047273930175">"Lokið"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Tilkynningastýringar <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Litur og útlit"</string>
     <string name="night_mode" msgid="3540405868248625488">"Næturstilling"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kvarða skjáinn"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ekki er hægt að nota rafhlöðusparnað meðan á hleðslu stendur"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Rafhlöðusparnaður"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Dregur úr afköstum og bakgrunnsgögnum"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Hnappur <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Til baka"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Upp"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Niður"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vinstri"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Hægri"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Miðja"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Bilslá"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Bakklykill"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Spila/gera hlé"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stöðva"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Áfram"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Fyrri"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spóla til baka"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Spóla áfram"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tölulykill <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Kerfi"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Heim"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nýlegt"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Færa upp"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Færa til vinstri"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Færa til hægri"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings_tv.xml b/packages/SystemUI/res/values-is-rIS/strings_tv.xml
index 053beaf..09c67ec 100644
--- a/packages/SystemUI/res/values-is-rIS/strings_tv.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Haltu "<b>"HOME"</b>"-hnappinum inni til að stjórna innfelldri mynd"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Haltu „Home“-hnappinum inni til að stjórna innfelldri mynd"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Ég skil"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Hunsa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 5ccc39c..591bf0d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Posizione stabilita dal GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Richieste di accesso alla posizione attive"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Impostazioni di notifica"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Impostazioni di <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Lo schermo ruoterà automaticamente."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossibile avviare <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"L\'app <xliff:g id="APP">%s</xliff:g> è stata disattivata in modalità provvisoria."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Cronologia"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Cancella"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Cancella tutto"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Questa app non supporta la modalità multi-finestra"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"L\'app non supporta la modalità multi-finestra"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisione in orizzontale"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Mostra in cima all\'elenco delle notifiche, visualizza sullo schermo e attiva l\'audio"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Altre impostazioni"</string>
     <string name="notification_done" msgid="5279426047273930175">"Fine"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Controlli di notifica per <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Colore e aspetto"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modalità notturna"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibra display"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Risparmio energetico non disponibile durante la ricarica"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Risparmio energetico"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Riduce le prestazioni e i dati in background"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Pulsante <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home page"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Indietro"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Su"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Giù"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Sinistra"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Destra"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Al centro"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Scheda"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Spazio"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Invio"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pausa"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Interrompi"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Avanti"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Precedente"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Riavvolgi"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avanza velocemente"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Pagina su"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Pagina giù"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Elimina"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home page"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fine"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"INS"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Bloc Num"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tastierino numerico <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recenti"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Sposta su"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sposta a sinistra"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sposta a destra"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml
index 5001b95..4ea019b 100644
--- a/packages/SystemUI/res/values-it/strings_tv.xml
+++ b/packages/SystemUI/res/values-it/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Tieni premuto "<b>"HOME"</b>" per controllare PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Tieni premuto il pulsante HOME per controllare PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignora"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 52c83ba..7e0122d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -238,8 +238,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"‏מיקום מוגדר על ידי GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"בקשות מיקום פעילות"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"הגדרות עבור הודעות"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"הגדרות <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
@@ -312,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"לא ניתן היה להפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> מושבת במצב בטוח."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"היסטוריה"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"נקה"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"נקה הכל"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"אפליקציה זו אינה תומכת בריבוי חלונות"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"האפליקציה אינה תומכת בריבוי חלונות"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"פיצול אופקי"</string>
@@ -482,8 +480,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"הצג בראש רשימת ההודעות, הצג לרגע על גבי המסך ואשר השמעת צליל"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"הגדרות נוספות"</string>
     <string name="notification_done" msgid="5279426047273930175">"סיום"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> פקדי הודעות"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"צבע ומראה"</string>
     <string name="night_mode" msgid="3540405868248625488">"מצב לילה"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"כיול תצוגה"</string>
@@ -503,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"חיסכון בסוללה"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"מפחית את רמת הביצועים ואת נתוני הרקע"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"לחצן <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"דף הבית"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"הקודם"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"למעלה"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"למטה"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"שמאלה"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ימינה"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"מרכז"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"כרטיסייה"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"רווח"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"BACKSPACE"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"הפעל/השהה"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"עצור"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"הבא"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"הקודם"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"הרץ אחורה"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"הרץ קדימה"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"דפדוף למעלה"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"דפדוף למטה"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"מחיקה"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"דף הבית"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"סיום"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"הזן"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"‏מקש Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"מקלדת נומרית <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"מערכת"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"דף הבית"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"אחרונים"</string>
@@ -562,4 +585,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"הזז למעלה"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"הזז שמאלה"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"הזז ימינה"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"ייתכן שהאפליקציה לא תפעל עם ריבוי חלונות"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml
index f4d4094..9130d53 100644
--- a/packages/SystemUI/res/values-iw/strings_tv.xml
+++ b/packages/SystemUI/res/values-iw/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"‏לחץ לחיצה ארוכה על "<b>"דף הבית"</b>" כדי לשלוט ב-PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"‏לחץ לחיצה ממושכת על לחצן דף הבית כדי לשלוט ב-PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"הבנתי"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"דחה"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index f7aacee..36c0e1a 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"現在地リクエストがアクティブ"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"他 <xliff:g id="NUMBER">%s</xliff:g> 件"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知設定"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>の設定"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"画面は自動的に回転します。"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>を開始できません。"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」はセーフモードでは無効になります。"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"履歴"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"消去"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"すべて消去"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"このアプリはマルチウィンドウに対応していません"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"アプリはマルチウィンドウに対応していません"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"横に分割"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"通知リストの先頭に表示し、画面に数秒間表示し、音声でも知らせる"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"詳細設定"</string>
     <string name="notification_done" msgid="5279426047273930175">"完了"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」の通知の管理"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"色と表示"</string>
     <string name="night_mode" msgid="3540405868248625488">"夜間モード"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"表示の調整"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電中はバッテリー セーバーは利用できません"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"バッテリー セーバー"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"パフォーマンスとバックグラウンド データを制限します"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> ボタン"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"戻る"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"上"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"下"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"左"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"右"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"中央"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"再生 / 一時停止"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"停止"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"次へ"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"前へ"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"巻き戻し"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"早送り"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"PageUp"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"PageDown"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"NumLock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"テンキーの <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"システム"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ホーム"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"上に移動"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"左に移動"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"右に移動"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"アプリはマルチウィンドウでは動作しないことがあります"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
index a4c49b3..0f0032f 100644
--- a/packages/SystemUI/res/values-ja/strings_tv.xml
+++ b/packages/SystemUI/res/values-ja/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP を管理するには ["<b>"ホーム"</b>"] を押し続けます"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP を管理するには [ホーム] ボタンを押し続けます"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"閉じる"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"閉じる"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 9730323..0e6f335 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-ით დადგენილი მდებარეობა"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"მდებარეობის მოთხოვნები აქტიურია"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ყველა შეტყობინების წაშლა"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"შეტყობინების პარამეტრები"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> პარამეტრები"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ეკრანი შეტრიალდება ავტომატურად."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-ის გამოძახება ვერ მოხერხდა."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> გათიშულია უსაფრთხო რეჟიმში."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ისტორია"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"გასუფთავება"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ყველას გასუფთავება"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"მრავალი ფანჯრის რეჟიმი არ არის მხარდაჭერილი ამ აპის მიერ"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"მრავალი ფანჯრის რეჟიმი არ არის მხარდაჭერილი აპის მიერ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ჰორიზონტალური გაყოფა"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"შეტყობინებების სიის თავში ჩვენება, პირდაპირ ეკრანზე გამოჩენა და ხმის დაშვება"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"დამატებითი პარამეტრები"</string>
     <string name="notification_done" msgid="5279426047273930175">"მზადაა"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> შეტყობინებების მართვის საშუალებები"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"ფერი და იერსახე"</string>
     <string name="night_mode" msgid="3540405868248625488">"ღამის რეჟიმი"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ეკრანის კალიბრაცია"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ბატარეის დამზოგი დატენვისას მიწვდომელია"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ბატარეის დამზოგი"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ამცირებს წარმადობას და ფონურ მონაცემებს"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"ღილაკი „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"უკან"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ზემოთ"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ქვემოთ"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"მარცხნივ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"მარჯვნივ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ცენტრში"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"შორისი"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"დაკვრა/პაუზა"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"შეწყვეტა"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"შემდეგი"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"წინა"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"უკან გადახვევა"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"წინ გადახვევა"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"რიცხვთა პანელი <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"სისტემა"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"მთავარი"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ბოლოს გამოყენებული"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ზემოთ გადატანა"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"მარცხნივ გადატანა"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"მარჯვნივ გადატანა"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
index 3a556ae..7d615ba 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP-ის სამართავად, გეჭიროთ "<b>"მთავარ ღილაკზე"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP-ის სამართავად, ხანგრძლივად დააჭირეთ მთავარ ღილაკს"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"გასაგებია"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"დახურვა"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index f6c1152..0a06bdf 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Орын GPS арқылы орнатылған"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Орын өтініштері қосылған"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Барлық хабарларды жойыңыз."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Хабарландыру параметрлері"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> параметрлері"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматты түрде бұрылады."</string>
@@ -310,8 +309,8 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"іздеу"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> іске қосу мүмкін болмады."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> қауіпсіз режимде өшіріледі."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Тарих"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Тазалау"</string>
+    <!-- no translation found for recents_stack_action_button_label (6593727103310426253) -->
+    <skip />
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Бұл қолданба көп терезені қолдамайды"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Қолданба көп терезені қолдамайды"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Бөлінген көлденең"</string>
@@ -480,8 +479,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Хабарландырулар тізімінің жоғарғы жағында көрсету, экранда көрсету және дыбысқа рұқсат ету"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Қосымша параметрлер"</string>
     <string name="notification_done" msgid="5279426047273930175">"Дайын"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> хабарландыруларды басқару элементтері"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Түс және сыртқы түрі"</string>
     <string name="night_mode" msgid="3540405868248625488">"Түнгі режим"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Дисплейді калибрлеу"</string>
@@ -501,6 +499,58 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Зарядтау кезінде Батарея үнемдегіш қол жетімді емес"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батарея үнемдегіш"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Өнімділікті және фондық деректерді азайтады"</string>
+    <!-- no translation found for keyboard_key_button_template (6230056639734377300) -->
+    <skip />
+    <!-- no translation found for keyboard_key_home (2243500072071305073) -->
+    <skip />
+    <!-- no translation found for keyboard_key_back (2337450286042721351) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_up (5584144111755734686) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (7331518671788337815) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (1346446024676962251) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (3317323247127515341) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_center (2566737770049304658) -->
+    <skip />
+    <!-- no translation found for keyboard_key_tab (3871485650463164476) -->
+    <skip />
+    <!-- no translation found for keyboard_key_space (2499861316311153293) -->
+    <skip />
+    <!-- no translation found for keyboard_key_enter (5739632123216118137) -->
+    <skip />
+    <!-- no translation found for keyboard_key_backspace (1559580097512385854) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_play_pause (3861975717393887428) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_stop (2859963958595908962) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_next (1894394911630345607) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_previous (4256072387192967261) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_rewind (2654808213360820186) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_fast_forward (3849417047738200605) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_up (5654098530106845603) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_down (8720502083731906136) -->
+    <skip />
+    <!-- no translation found for keyboard_key_forward_del (1391451334716490176) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_home (2765693292069487486) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_end (5901174332047975247) -->
+    <skip />
+    <!-- no translation found for keyboard_key_insert (8530501581636082614) -->
+    <skip />
+    <!-- no translation found for keyboard_key_num_lock (5052537581246772117) -->
+    <skip />
+    <!-- no translation found for keyboard_key_numpad_template (8729216555174634026) -->
+    <skip />
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Жүйе"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Негізгі бет"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Жақындағылар"</string>
@@ -559,4 +609,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Жоғары қарай жылжыту"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Солға жылжыту"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Оңға жылжыту"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Қолданба көп тереземен жұмыс істемеуі мүмкін"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
index ef930b0..06c84a8 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP басқару үшін "<b>"HOME"</b>" басып тұрыңыз"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP функциясын басқару үшін HOME түймесін басып тұрыңыз"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Түсіндім"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Жабу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 4a306da..46b1435 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"ទីតាំង​​​​​កំណត់​ដោយ GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"សំណើ​ទីតាំង​សកម្ម"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"សម្អាត​ការ​ជូន​ដំណឹង​ទាំងអស់។"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"​កំណត់​ការ​ជូនដំណឹង"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"ការ​កំណត់ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"នឹង​បង្វិល​អេក្រង់​ស្វ័យ​ប្រវត្តិ។"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"មិន​អាច​ចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ត្រូវបានបិទដំណើរការក្នុងរបៀបសុវត្ថិភាព"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ប្រវត្តិ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"សម្អាត"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ជម្រះទាំងអស់"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"កម្មវិធីនេះមិនគាំទ្រផ្ទាំងវិដូច្រើនទេ"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"កម្មវិធីមិនគាំទ្រផ្ទាំងវិដូច្រើនទេ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"បំបែកផ្តេក"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"បង្ហាញនៅផ្នែកខាងលើបញ្ជីនៃការជូនដំណឹង លោតបង្ហាញនៅលើអេក្រង់ និងអនុញ្ញាតឲ្យបន្លឺសំឡេង"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"ការកំណត់ច្រើនទៀត"</string>
     <string name="notification_done" msgid="5279426047273930175">"រួចរាល់"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"អង្គគ្រប់គ្រងការជូនដំណឹង <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"ពណ៌ និងរូបរាង"</string>
     <string name="night_mode" msgid="3540405868248625488">"របៀបពេលយប់"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ការបង្ហាញក្រិត"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"កម្មវិធីសន្សំថ្ម"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"កាត់បន្ថយប្រតិបត្តិការ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"ប៊ូតុង <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ប្រព័ន្ធ"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ដើម"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ថ្មីៗ"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ផ្លាស់ទីឡើងលើ"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ផ្លាស់ទីទៅឆ្វេង"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ផ្លាស់ទីទៅស្តាំ"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"កម្មវិធីអាចនឹងមិនដំណើរការជាមួយពហុវិនដូទេ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings_tv.xml b/packages/SystemUI/res/values-km-rKH/strings_tv.xml
index 8076010..123cb76 100644
--- a/packages/SystemUI/res/values-km-rKH/strings_tv.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"សង្កត់ប៊ូតុង "<b>"ដើម"</b>" ដើម្បីគ្រប់គ្រង PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"ចុច និងសង្កត់ប៊ូតុង ដើម ដើម្បីគ្រប់គ្រង PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"យល់ហើយ"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"បដិសេធ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 046d5d8..f26abdc 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"ಸ್ಥಾನವನ್ನು GPS ಮೂಲಕ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"ಸ್ಥಾನ ವಿನಂತಿಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ಅಧಿಸೂಚನೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ಪರದೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಿರುಗುತ್ತದೆ."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ಹುಡುಕಾಟ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾದ್ಯವಿಲ್ಲ."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ಇತಿಹಾಸ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ತೆರವುಗೊಳಿಸು"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸು"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಬಹು-ವಿಂಡೊಗಳನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ಅಪ್ಲಿಕೇಶನ್ ಬಹು-ವಿಂಡೊಗಳನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ಅಡ್ಡಲಾಗಿ ವಿಭಜಿಸಿದ"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"ಅಧಿಸೂಚನೆಗಳ ಪಟ್ಟಿಯ ಮೇಲ್ಭಾಗದಲ್ಲಿ ತೋರಿಸು, ಪರದೆಯನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ಧ್ವನಿ ಅನುಮತಿಸಿ"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="notification_done" msgid="5279426047273930175">"ಮುಗಿದಿದೆ"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"ಬಣ್ಣ ಮತ್ತು ಗೋಚರತೆ"</string>
     <string name="night_mode" msgid="3540405868248625488">"ರಾತ್ರಿ ಮೋಡ್"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ಅಣಿಗೊಳಿಸುವ ಪ್ರದರ್ಶನ"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ಚಾರ್ಜಿಂಗ್ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಸೇವರ್‌‌ ಲಭ್ಯವಿರುವುದಿಲ್ಲ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ಬ್ಯಾಟರಿ ಸೇವರ್‌‌"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> ಬಟನ್"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"ಹಿಂದೆ"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ಮೇಲೆ"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ಕೆಳಗೆ"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ಎಡ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ಬಲ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ಮಧ್ಯ"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"ಸ್ಪೇಸ್"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"ಮುಂದೆ"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ಹಿಂದೆ"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ಫಾಸ್ಟ್ ಫಾರ್ವರ್ಡ್"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> ಸಂಖ್ಯೆಪ್ಯಾಡ್"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ಸಿಸ್ಟಂ"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ಮುಖಪುಟ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ಇತ್ತೀಚಿನವುಗಳು"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ಮೇಲೆ ಸರಿಸಿ"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"ಬಹು ವಿಂಡೋದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings_tv.xml b/packages/SystemUI/res/values-kn-rIN/strings_tv.xml
index d275de6..6491587 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP ನಿಯಂತ್ರಿಸಲು "<b>"HOME"</b>" ಕೀಯನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP ನಿಯಂತ್ರಿಸಲು HOME ಬಟನ್ ಒತ್ತಿರಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"ಅರ್ಥವಾಯಿತು"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"ವಜಾಗೊಳಿಸಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 5e16258..5e28f0b 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"위치 요청 있음"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g>개 더보기"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"알림 설정"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> 설정"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"화면이 자동으로 회전됩니다."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>을(를) 시작할 수 없습니다."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>은(는) 안전 모드에서 사용 중지됩니다."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"기록"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"삭제"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"모두 지우기"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"이 앱은 다중 창을 지원하지 않습니다."</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"앱이 다중 창을 지원하지 않습니다."</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"수평 분할"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"알림 목록 맨 위에 표시, 화면에 표시하고 소리로 알림"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"설정 더보기"</string>
     <string name="notification_done" msgid="5279426047273930175">"완료"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> 알림 관리"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"색상 및 모양"</string>
     <string name="night_mode" msgid="3540405868248625488">"야간 모드"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"디스플레이 보정"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"충전하는 동안 배터리 세이버는 사용할 수 없습니다."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"배터리 세이버"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"성능 및 백그라운드 데이터를 줄입니다."</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> 버튼"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"뒤로"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"위쪽"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"아래쪽"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"왼쪽"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"오른쪽"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"중앙"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"재생/일시중지"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"중지"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"다음"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"이전"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"되감기"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"빨리 감기"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"숫자 패드 <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"시스템"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"홈"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"최근"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"위로 이동"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"왼쪽으로 이동"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"오른쪽으로 이동"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml
index 52747b4..da3ab9e 100644
--- a/packages/SystemUI/res/values-ko/strings_tv.xml
+++ b/packages/SystemUI/res/values-ko/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109"><b>"HOME"</b>"을 눌러 PIP 제어"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"홈 버튼을 길게 눌러 PIP 제어"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"확인"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"닫기"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 60db439..9cd5f60 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS боюнча аныкталган жайгашуу"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Жайгаштыруу талаптары иштелүүдө"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Бардык эскертмелерди тазалоо."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Эскертме жөндөөлөрү"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> жөндөөлөрү"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматтык түрдө бурулат."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"издөө"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> баштай алган жок."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> коопсуз режиминде өчүрүлдү."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Таржымал"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Тазалоо"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Баарын тазалоо"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Бул колдонмодо бир нече терезе режими колдоого алынбайт"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Колдонмодо бир нече терезе режими колдоого алынбайт"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Туурасынан бөлүү"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Эскертмелер тизмесинин эң башында көрсөтүлүп, үн менен коштолуп, экранга чыгарылсын"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Дагы жөндөөлөр"</string>
     <string name="notification_done" msgid="5279426047273930175">"Аткарылды"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> эскертмесин көзөмөлдөө каражаттары"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Түсү жана көрүнүшү"</string>
     <string name="night_mode" msgid="3540405868248625488">"Түнкү режим"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Дисплейди калибрлөө"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Батареяны үнөмдөгүч түзмөк кубатталып жатканда иштебейт"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батареяны үнөмдөгүч"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Иштин майнаптуулугун начарлатып, фондук дайындарды чектейт"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> баскычы"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Башкы бет"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Артка"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Өйдө"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Төмөн"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Солго"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Оңго"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Экрандын ортосунда"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Өтмөк"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Боштук"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Киргизүү"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Артка өчүрүү"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Ойнотуу/Тындыруу"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Токтотуу"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Кийинки"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Мурунку"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Артка түрүү"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Алдыга түрүү"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Бир бет жогору"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Бир бет төмөн"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Жок кылуу"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Башкы бет"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Бүтүрүү"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Салуу"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Тутум"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Башкы бет"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Акыркылар"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Жогору жылдыруу"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Солго жылдыруу"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Оңго жылдыруу"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
index e54aae2..b030542 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109"><b>"БАШКЫ БЕТ"</b>" басып туруп PIP\'ти башкарыңыз"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP башкаруу үчүн БАШКЫ БЕТ баскычын басып, кармап туруңуз"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Түшүндүм"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Көз жаздымда калтыруу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml
index 43e7bac..f7e2344 100644
--- a/packages/SystemUI/res/values-land/config.xml
+++ b/packages/SystemUI/res/values-land/config.xml
@@ -28,14 +28,4 @@
 
     <!-- We have only space for one notification on phone landscape layouts. -->
     <integer name="keyguard_max_notification_count">1</integer>
-
-    <!-- Recents: The relative range of visible tasks from the current scroll position
-         while the stack is focused. -->
-    <item name="recents_layout_focused_range_min" format="float" type="integer">-3</item>
-    <item name="recents_layout_focused_range_max" format="float" type="integer">2</item>
-
-    <!-- Recents: The relative range of visible tasks from the current scroll position
-         while the stack is not focused. -->
-    <item name="recents_layout_unfocused_range_min" format="float" type="integer">-2</item>
-    <item name="recents_layout_unfocused_range_max" format="float" type="integer">1.5</item>
 </resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 585984c..26a81c8 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -22,9 +22,6 @@
     <!-- Standard notification gravity -->
     <integer name="notification_panel_layout_gravity">@integer/standard_notification_panel_layout_gravity</integer>
 
-    <!-- The size of the initial peek area at the bottom of the stack (above the nav bar). -->
-    <dimen name="recents_initial_bottom_peek_size">@dimen/recents_task_bar_height</dimen>
-
     <dimen name="docked_divider_handle_width">2dp</dimen>
     <dimen name="docked_divider_handle_height">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index ecb1eb3..182abe9 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"ສະຖານທີ່ກຳນົດໂດຍ GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"ການຮ້ອງຂໍສະຖານທີ່ທີ່ເຮັດວຽກຢູ່"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ລຶບການແຈ້ງເຕືອນທັງໝົດ."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"​ການ​ຕັ້ງ​ຄ່າ​ການ​ແຈ້ງ​ເຕືອນ"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"ການ​ຕັ້ງ​ຄ່າ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ໜ້າຈໍຈະໝຸນໂດຍອັດຕະໂນມັດ."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"ບໍ່​ສາ​ມາດ​ເລີ່ມ <xliff:g id="APP">%s</xliff:g> ໄດ້."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ຖືກປິດໃຊ້ໃນໂໝດຄວາມມປອດໄພ."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ປະຫວັດ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ລຶບ"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ລຶບລ້າງທັງໝົດ"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ແອັບນີ້ບໍ່ຮອງຮັບຫຼາຍໜ້າຈໍ"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ແອັບບໍ່ຮອງຮັບຫຼາຍໜ້າຈໍ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ການ​ແຍກ​ລວງ​ຂວາງ"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"ສະແດງຢູ່ເທິງສຸດຂອງລາຍການແຈ້ງເຕືອນ, ແຈ້ງໄປໜ້າຈໍ ແລະ ອະນຸຍາດໃຫ້ໃຊ້ສຽງໄດ້"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"​ການ​ຕັ້ງ​ຄ່າ​ເພີ່ມ​ເຕີມ"</string>
     <string name="notification_done" msgid="5279426047273930175">"ສຳເລັດແລ້ວ"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"ການຄວບຄຸມການແຈ້ງເຕືອນ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"ສີ ແລະ ລັກສະນະ"</string>
     <string name="night_mode" msgid="3540405868248625488">"ໂໝດກາງຄືນ"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ປັບໜ້າຈໍ"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ຕົວປະຢັດແບັດເຕີຣີບໍ່ມີໃຫ້ນຳໃຊ້ໃນລະຫວ່າງການສາກ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ຕົວປະຢັດ​ແບັດເຕີຣີ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ຫຼຸດ​ປະ​ສິ​ທິ​ພາບ​ການໃຊ້ງານ ແລະ ​ຂໍ້​ມູນ​ພື້ນຫຼັງ"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"ປຸ່ມ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"ກັບຄືນ"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ຂຶ້ນ"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ລົງ"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ຊ້າຍ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ຂວາ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ເຄິ່ງກາງ"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ຫຼິ້ນ/ຢຸດຊົ່ວຄາວ"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ຢຸດ"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"ຕໍ່ໄປ"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ກ່ອນໜ້າ"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ຣີວາຍກັບ"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ເລື່ອນໄປໜ້າ"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ລະບົບ"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"​ໜ້າຫຼັກ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ຫາ​ກໍ​ໃຊ້"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ເລື່ອນຂຶ້ນ"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ເລື່ອນຊ້າຍ"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ເລື່ອນຂວາ"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ກັບຫຼາຍໜ້າຈໍ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
index 911dcf9..6e36d3f 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"ກົດ "<b>"HOME"</b>" ຄ້າງໄວ້ເພື່ອຄວບຄຸມ PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"ແຕະປຸ່ມ HOME ຄ້າງໄວ້ເພື່ອຄວບຄຸມຮູບນ້ອຍ"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"ເຂົ້າໃຈແລ້ວ"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"ປິດໄວ້"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4de42c0..f3b6842 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -238,8 +238,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Vietovės užklausos aktyvios"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Dar <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Pranešimų nustatymai"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"„<xliff:g id="APP_NAME">%s</xliff:g>“ nustatymai"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekranas bus sukamas automatiškai."</string>
@@ -312,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nepavyko paleisti <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Programa „<xliff:g id="APP">%s</xliff:g>“ išjungta saugos režimu."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Istorija"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Išvalyti"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Išvalyti viską"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ši programa nepalaiko kelių langų režimo"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Programa nepalaiko kelių langų režimo"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontalus skaidymas"</string>
@@ -482,8 +480,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Rodyti pranešimų sąrašo viršuje, rodyti ekrane ir leisti skambėti"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Daugiau nustatymų"</string>
     <string name="notification_done" msgid="5279426047273930175">"Atlikta"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ pranešimų valdikliai"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Spalva ir išvaizda"</string>
     <string name="night_mode" msgid="3540405868248625488">"Naktinis režimas"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibruoti ekraną"</string>
@@ -503,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumuliatoriaus tausojimo priemonė nepasiekiama įkraunant"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumuliatoriaus tausojimo priemonė"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sumažinamas našumas ir foninių duomenų naudojimas"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Mygtukas <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Pagrindinis"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Atgal"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Aukštyn"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Žemyn"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Kairėn"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Dešinėn"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centras"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabuliavimo klavišas"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Tarpas"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Įvesti"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Naikinimo klavišas"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Leisti / pristabdyti"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Sustabdyti"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Kitas"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Ankstesnis"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Sukti atgal"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Sukti pirmyn"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Ankstesnis puslapis"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Tolesnis puslapis"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ištrinti"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Pagrindinis"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Baigti"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Įterpti"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Skaičių režimas"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Klaviatūros skaitmenų sritis <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pagrindinis ekranas"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Naujausios veiklos ekranas"</string>
@@ -561,4 +584,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Perkelti aukštyn"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Perkelti kairėn"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Perkelti dešinėn"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml
index 928b4c7..c8fce8a 100644
--- a/packages/SystemUI/res/values-lt/strings_tv.xml
+++ b/packages/SystemUI/res/values-lt/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Kad vald. PIP, pal. pasp. m. "<b>"PAGRINDINIS"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Jei norite valdyti PIP, paspauskite ir palaikykite pagrindinio puslapio mygtuką"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Supratau"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Atsisakyti"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index f473971..8983cde 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -310,8 +310,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nevarēja palaist lietotni <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Lietotne <xliff:g id="APP">%s</xliff:g> ir atspējota drošajā režīmā."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Vēsture"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Notīrīt"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Notīrīt visu"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Šajā lietotnē netiek atbalstīts vairāku logu režīms."</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Lietotnē netiek atbalstīts vairāku logu režīms"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontāls dalījums"</string>
@@ -500,6 +499,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumulatora jaudas taupīšanas režīms uzlādes laikā nav pieejams."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumulatora jaudas taupīšanas režīms"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Samazina veiktspēju un fona datus."</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Poga <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Sākumvietas taustiņš"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Atpakaļ"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Uz augšu"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Uz leju"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Pa kreisi"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Pa labi"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centrā"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulēšanas taustiņš"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Atstarpe"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Ievadīšanas taustiņš"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Atpakaļatkāpes taustiņš"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Atskaņot/apturēt"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Apturēt"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Nākamais"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Iepriekšējais"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Attīt atpakaļ"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Pārtīt uz priekšu"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Lapa uz augšu"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Lapa uz leju"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Dzēšanas taustiņš"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Sākumvietas taustiņš"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Beigvietas taustiņš"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Ievietošanas taustiņš"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Ciparslēga taustiņš"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Cipartastatūra <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistēma"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Sākums"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Pēdējie"</string>
@@ -558,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Pārvietot uz augšu"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Pārvietot pa kreisi"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Pārvietot pa labi"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 1666273..954a9d0 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Локацијата е поставена со ГПС"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Активни барања за локација"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Исчисти ги сите известувања."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Поставки на известувања"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Поставки на <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранот ќе ротира автоматски."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"пребарај"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не може да се вклучи."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> е оневозможен во безбеден режим."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Историја"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Исчисти"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Исчисти ги сите"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Апликацијава не поддржува повеќе прозорци"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Апликацијата не поддржува повеќе прозорци"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Раздели хоризонтално"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Прикажувај ги на врвот на списокот со известувања, ѕиркање на екранот и овозможи звук"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Повеќе поставки"</string>
     <string name="notification_done" msgid="5279426047273930175">"Готово"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Контроли за известувања на <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Боја и изглед"</string>
     <string name="night_mode" msgid="3540405868248625488">"Ноќен режим"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Калибрирај го екранот"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Штедачот на батерија не е достапен при полнење"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Штедач на батерија"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ја намалува изведбата и податоците во заднина"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Копче <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Почетна страница"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Стрелка нагоре"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Стрелка надолу"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Стрелка налево"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Стрелка надесно"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Центар"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Картичка"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Празно место"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Внеси"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Бришење наназад"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Пушти/Паузирај"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Сопри"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Следно"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Претходно"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Премотување наназад"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Брзо премотување нанапред"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Страница нагоре"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Страница надолу"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Избриши"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Почетна страница"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Крај"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Вметни"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетна страница"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Неодамнешни"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Преместете нагоре"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Преместете налево"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Преместете надесно"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
index 10bf41f..2d6da0c 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Задржете "<b>"ДОМА"</b>" за кон. PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Притиснете и задржете го копчето ДОМА за контролирање PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрав"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Отфрли"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 882f189..1149147 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"ലൊക്കേഷൻ സജ്ജീകരിച്ചത് GPS ആണ്"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"ലൊക്കേഷൻ അഭ്യർത്ഥനകൾ സജീവമാണ്"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"എല്ലാ വിവരങ്ങളും മായ്‌ക്കുക."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"അറിയിപ്പ് ക്രമീകരണങ്ങൾ"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ക്രമീകരണങ്ങൾ"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"സ്‌ക്രീൻ യാന്ത്രികമായി തിരിയും."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"തിരയുക"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കാനായില്ല."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"സുരക്ഷിത മോഡിൽ <xliff:g id="APP">%s</xliff:g> പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ചരിത്രം"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"മായ്‌ക്കുക"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ഒന്നിലധികം വിൻഡോകളെ ഈ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ഒന്നിലധികം വിൻഡോകളെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"തിരശ്ചീനമായി വേർതിരിക്കുക"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"അറിയിപ്പ് ലിസ്റ്റിന്റെ ഏറ്റവും മുകളിൽ കാണിക്കുക, ശബ്ദമുണ്ടാക്കുക"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"കൂടുതൽ ക്രമീകരണം"</string>
     <string name="notification_done" msgid="5279426047273930175">"പൂർത്തിയായി"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> അറിയിപ്പ് നിയന്ത്രണങ്ങൾ"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"വർണ്ണവും രൂപഭാവവും"</string>
     <string name="night_mode" msgid="3540405868248625488">"നൈറ്റ് മോഡ്"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ഡിസ്പ്ലേ കാലിബ്രേറ്റുചെയ്യുക"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി സേവർ ലഭ്യമല്ല"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ബാറ്ററി സേവർ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്‌ക്കുന്നു"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"ബട്ടൺ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"ഹോം"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"ബാക്ക്"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"മുകളിലേക്ക്"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"താഴേക്ക്"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ഇടത്"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"വലത്"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"മധ്യം"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"ടാബ്"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"സ്പെയ്സ്"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"എന്റർ"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"ബാക്ക്‌സ്‍പെയ്‍സ്"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"പ്ലേ ചെയ്യുക/താൽക്കാലികമായി നിർത്തുക"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"നിർത്തുക"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"അടുത്തത്"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"മുമ്പത്തേത്"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"റിവൈൻഡ്"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ഫാസ്റ്റ് ഫോർവേഡ്"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"പേജ് അപ്പ്"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"പേജ് ഡൗൺ"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ഡിലീറ്റ്"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"ഹോം"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"എൻഡ്"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"ഇൻസേർട്ട്"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"നം ലോക്ക്"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"നംപാഡ് <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"സിസ്‌റ്റം"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"വീട്"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"പുതിയവ"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"മുകളിലേക്ക് നീക്കുക"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ഇടത്തേക്ക് നീക്കുക"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"വലത്തേക്ക് നീക്കുക"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"മൾട്ടി-വിൻഡോയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
index c054eed..09fe4ce 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP നിയന്ത്രിക്കാൻ "<b>"ഹോം"</b>" പിടിക്കുക"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP നിയന്ത്രിക്കാൻ ഹോം ബട്ടൺ അമർത്തിപ്പിടിക്കുക"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"മനസ്സിലായി"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"ഡിസ്മിസ് ചെയ്യുക"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index b9ddad7..bafb558 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -234,8 +234,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS байршил"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Байршлын хүсэлтүүд идэвхтэй"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Бүх мэдэгдлийг цэвэрлэх."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Мэдэгдлийн тохиргоо"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> тохиргоо"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Дэлгэц автоматаар эргэнэ."</string>
@@ -308,8 +307,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж чадсангүй."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>-г аюулгүй горимд идэвхгүй болгосон."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Түүх"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Устгах"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Бүгдийг арилгах"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Энэ апп олон цонхыг дэмждэггүй"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Апп олон цонхыг дэмждэггүй"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хэвтээ чиглэлд хуваах"</string>
@@ -478,8 +476,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Мэдэгдлийг жагсаалтын эхэнд яаралтай дуутай харуулах"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Бусад тохиргоо"</string>
     <string name="notification_done" msgid="5279426047273930175">"Дууссан"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> мэдэгдлийн хяналт"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Өнгө, харагдах байдал"</string>
     <string name="night_mode" msgid="3540405868248625488">"Шөнийн горим"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Дэлгэцийг тохируулах"</string>
@@ -499,6 +496,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Цэнэглэх үед тэжээл хэмнэгч ажиллахгүй"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Тэжээл хэмнэгч"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Гүйцэтгэл болон дэвсгэрийн датаг багасгадаг"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> товчлуур"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Нүүр хуудас"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Буцах"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Дээш"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Доош"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Зүүн"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Баруун"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Гол хэсэг"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Чихтэй хуудас"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Зай"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Оруулах"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Арилгах"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Тоглуулах/Түр зогсоох"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Зогсоох"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Дараах"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Өмнөх"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Буцааж хураах"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Хурдан урагшлуулах"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Хуудас дээш"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Хуудас доош"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Устгах"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Нүүр хуудас"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Төгсгөл"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Оруулах"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Тоо бичих горим"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Тоо бичих товчлуур <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Нүүр хуудас"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Саяхны"</string>
@@ -557,4 +580,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Дээш зөөх"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Зүүн тийш зөөх"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Баруун тийш зөөх"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Олон цонхтой үед апп ажиллахгүй байж болзошгүй"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
index 54f2282..ca522d3 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP-г удирдахын тулд "<b>"HOME"</b>" товчлуурыг дарна уу"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP-г удирдахын тулд НҮҮР ХУУДАС товчлуурыг дараад хүлээнэ үү"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Ойлголоо"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Хаах"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index e65897c..00d65cd 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारे स्थान सेट केले"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"स्थान विनंत्या सक्रिय"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"सर्व सूचना साफ करा."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"सूचना सेटिंग्ज"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिंग्ज"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वयंचलितपणे फिरेल."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"शोधा"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करणे शक्य झाले नाही."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> सुरक्षित-मोडमध्ये अक्षम केला आहे."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"साफ करा"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"सर्व साफ करा"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"हा अॅप एकाधिक-विंडोला समर्थन देत नाही"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"अॅप एकाधिक-विंडोला समर्थन देत नाही"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज विभाजित करा"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"सूचनांच्या शीर्षस्थानी दर्शवा, स्क्रीनवर पहा आणि ध्वनीस अनुमती द्या"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"अधिक सेटिंग्ज"</string>
     <string name="notification_done" msgid="5279426047273930175">"पूर्ण झाले"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> सूचना नियंत्रणे"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"रंग आणि स्वरूप"</string>
     <string name="night_mode" msgid="3540405868248625488">"रात्र मोड"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"प्रदर्शनाचे मापन करा"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज करताना बॅटरी बचतकर्ता उपलब्ध नाही"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बॅटरी बचतकर्ता"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यप्रदर्शन आणि पार्श्वभूमी डेटा कमी करते"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"बटण <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"परत"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"वर"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"खाली"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"डावा"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"उजवा"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"मध्यवर्ती"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"टॅब"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"प्ले करा/विराम द्या"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"थांबा"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"पुढील"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"मागील"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"मागे न्या"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"पुढे करा"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"हटवा"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"घाला"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"सिस्टीम"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"मुख्यपृष्ठ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"अलीकडील"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"वर हलवा"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"डावीकडे हलवा"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"उजवीकडे हलवा"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings_tv.xml b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
index 6a29867..318e3e9 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP नियंत्रित करण्यासाठी "<b>"मुख्यपृष्ठ"</b>" धरून ठेवा"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP नियंत्रित करण्यासाठी मुख्यपृष्ठ बटण दाबा आणि धरून ठेवा"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"समजले"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"डिसमिस करा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 432110c..68ce748 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Tetapan pemberitahuan"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> tetapan"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrin akan berputar secara automatik."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulakan <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> dilumpuhkan dalam mod selamat."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Sejarah"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Kosongkan"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Kosongkan semua"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Apl ini tidak menyokong berbilang tetingkap"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Apl tidak menyokong berbilang tetingkap"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Mendatar Terpisah"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Tunjukkan pada bahagian atas senarai pemberitahuan, intai pada skrin dan benarkan bunyi"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Lagi tetapan"</string>
     <string name="notification_done" msgid="5279426047273930175">"Selesai"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kawalan pemberitahuan <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Warna dan penampilan"</string>
     <string name="night_mode" msgid="3540405868248625488">"Mod malam"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Tentukur paparan"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penjimat Bateri tidak tersedia semasa mengecas"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penjimat Bateri"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangkan prestasi dan data latar belakang"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Butang <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Skrin Utama"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Kembali"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Ke atas"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ke bawah"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Ke kiri"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Ke kanan"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Tengah"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Undur ruang"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Main/Jeda"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Berhenti"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seterusnya"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Sebelumnya"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Mandir"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Mara Laju"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Pad nombor <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Skrin Utama"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaharu"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Alih ke atas"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Alih ke kiri"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Alih ke kanan"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
index d358cc0..eb5af9e3 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Thn "<b>"SKRN UTMA"</b>" utk kwl PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Tekan dan tahan butang SKRIN UTAMA untuk mengawal PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ketepikan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 8994499..3cfc675 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ရှာဖွေရန်"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ကို ဘေးကင်းလုံခြုံသည့်မုဒ်တွင် ပိတ်ထားပါသည်။"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"မှတ်တမ်း"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ရှင်းလင်းပါ"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"အားလုံး ရှင်းလင်းပါ"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ဤအက်ပ်သည် ဝင်းဒိုးများစွာဖွင့်ခြင်းကို ပံ့ပိုးမထားပါ"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"အက်ပ်သည် ဝင်းဒိုးများစွာဖွင့်ခြင်းကို ပံ့ပိုးမထားပါ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ရေပြင်ညီ ပိုင်းမည်"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"အားသွင်းနေချိန်မှာ Battery Saver ကို သုံးမရပါ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"လုပ်ဆောင်မှု နှင့် နောက်ခံ ​ဒေတာကို လျော့နည်းစေပါသည်"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"ခလုတ် <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"ပင်မ"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"နောက်သို့"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"အပေါ်"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"အောက်"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ဘယ်"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ညာ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"ဌာန"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"တဘ်"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"နေရာခြားပါ"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"ဝင်ပါ"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"နောက်ပြန်ဖျက်ပါ"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ဖွင့်ပါ/ခဏရပ်ပါ"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ရပ်ပါ"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"ရှေ့သို့"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"အနောက်သို့"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"နောက်သို့ရစ်ပါ"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ရှေ့သို့ရစ်ပါ"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"အပေါ်စာမျက်နှာသို့သွားပါ"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"အောက်စာမျက်နှာသို့သွားပါ"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ဖျက်ပါ"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"ပင်မ"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"ပြီးပါပြီ"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"ထည့်ပါ"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"နံပါတ်လော့ခ်ချပါ"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"နံပါတ်ခလုတ်ခုံ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"စနစ်"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ပင်မ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"မကြာသေးခင်က"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"အပေါ်သို့ရွှေ့ပါ"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ဘယ်ဘက်သို့ရွှေ့ပါ"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ညာဘက်သို့ရွှေ့ပါ"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"အက်ပ်သည် ဝင်းဒိုးများတပြိုင်နက်ဖွင့်ခြင်းကို မပံ့ပိုးပါ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 9ee29ab..0a21abc 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kunne ikke starte <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er slått av i sikker modus."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Logg"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tøm"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tøm alt"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Denne appen har ikke støtte for flervindusmodus"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Appen har ikke støtte for flervindusmodus"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Del horisontalt"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparing er ikke tilgjengelig under lading"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparing"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduserer ytelsen og begrenser bakgrunnsdataene"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g>-knappen"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Startskjerm"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Tilbake"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Opp"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ned"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Venstre"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Høyre"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Midttasten"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Mellomrom"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Tilbaketasten"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Spill av / sett på pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stopp"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Neste"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Forrige"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spol tilbake"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Spol fremover"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Startskjerm"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> på talltastaturet"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startside"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nylige"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Flytt opp"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Flytt mot venstre"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Flytt mot høyre"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Appen fungerer kanskje ikke i Flervindusmodus"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 5b139d1..d2d4e97 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा स्थान सेट गरिएको"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोधहरू सक्रिय"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"सबै सूचनाहरू हटाउनुहोस्।"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"अधिसूचना सेटिङ्हरू"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिङ्हरू"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रिन स्वतः घुम्ने छ।"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"खोजी गर्नुहोस्"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"सुरु गर्न सकिएन <xliff:g id="APP">%s</xliff:g>।"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> लाई सुरक्षित-मोडमा असक्षम गरिएको छ।"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"मेटाउनुहोस्"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"सबै हटाउनुहोस्"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"यस अनुप्रयोगले बहु-विन्डोलाई समर्थन गर्दैन"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"अनुप्रयोगले बहु-विन्डोलाई समर्थन गर्दैन"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"तेर्सो रूपमा विभाजन गर्नुहोस्"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"सूचना सूचीको शीर्षमा देखाउने, स्क्रिनमा चियाउने र ध्वनि निकाल्न अनुमति दिने"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"थप सेटिङहरू"</string>
     <string name="notification_done" msgid="5279426047273930175">"सम्पन्‍न भयो"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> का सूचनाका लागि नियन्त्रणहरू"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"रंग र रूप"</string>
     <string name="night_mode" msgid="3540405868248625488">"रात्री मोड"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"प्रदर्शनको स्तर  मिलाउनुहोस्"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज गर्ने समयमा ब्याट्री सेभर उपलब्ध छैन"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ब्याट्री सेभर"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यसम्पादन र पृष्ठभूमि डेटा घटाउँछ"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> बटन"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"पछाडि"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"माथि"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"तल"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"बायाँ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"दायाँ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"केन्द्र"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"स्पेस"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"ब्याकस्पेस"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"प्ले गर्नुहोस्/पज गर्नुहोस्"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"रोक्नुहोस्"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"अर्को"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"अघिल्लो"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"रिवाइन्ड गर्नुहोस्"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"फास्ट फर्वार्ड"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"नमप्याड <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"प्रणाली"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"गृह"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हालैका"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"माथि सार्नुहोस्"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"बाँया सार्नुहोस्"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"दायाँ सार्नुहोस्"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"अनुप्रयोगले बहु-विन्डोमा काम नगर्न सक्छ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings_tv.xml b/packages/SystemUI/res/values-ne-rNP/strings_tv.xml
index 7234d3b..d9245d2 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings_tv.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP लाई नियन्त्रण गर्न "<b>"गृह"</b>" कुञ्जीलाई थिचिरहनुहोस्"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"IP लाई नियन्त्रण गर्न गृह बटनलाई थिची होल्ड गर्नुहोस्"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"बुझेँ"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"खारेज गर्नुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index b49cf66..42dea78 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kan <xliff:g id="APP">%s</xliff:g> niet starten."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is uitgeschakeld in de veilige modus"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Geschiedenis"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Wissen"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Alles wissen"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Deze app ondersteunt de modus voor meerdere vensters niet"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"App ondersteunt meerdere vensters niet"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontaal splitsen"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Accubesparing niet beschikbaar tijdens opladen"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Accubesparing"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vermindert de prestaties en achtergrondgegevens"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Knop <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Terug"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Omhoog"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Omlaag"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Links"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Rechts"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Midden"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Spatiebalk"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Afspelen/Onderbreken"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stoppen"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Volgende"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Vorige"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Terugspoelen"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Vooruitspoelen"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> op numeriek toetsenblok"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systeem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startpagina"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
@@ -557,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Omhoog"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Naar links"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Naar rechts"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index f67c51a..b58b2c8 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS ਵੱਲੋਂ ਸੈਟ ਕੀਤਾ ਨਿਰਧਾਰਿਤ ਸਥਾਨ"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸੇਵਾ ਬੇਨਤੀਆਂ ਸਕਿਰਿਆ"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਹਟਾਓ।"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ਸੈਟਿੰਗਾਂ"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ਸਕ੍ਰੀਨ ਆਟੋਮੈਟਿਕਲੀ ਰੋਟੇਟ ਕਰੇਗੀ।"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ਖੋਜੋ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਸੁਰੱਖਿਅਤ-ਮੋਡ ਵਿੱਚ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ।"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ਇਤਿਹਾਸ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ਸਾਫ਼ ਕਰੋ"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ਸਭ ਸਾਫ਼ ਕਰੋ"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ਇਹ ਐਪ ਮਲਟੀ-ਵਿੰਡੋ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ਐਪ ਮਲਟੀ-ਵਿੰਡੋ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ਹੌਰੀਜ਼ੌਂਟਲ ਸਪਲਿਟ"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"ਸੂਚਨਾਵਾਂ ਸੂਚੀ ਦੇ ਸਿਖਰ \'ਤੇ ਵਿਖਾਓ, ਸਕ੍ਰੀਨ \'ਤੇ ਝਲਕ ਵਿਖਾਉਣ ਅਤੇ ਧੁਨੀ ਦੀ ਮਨਜ਼ੂਰੀ ਦਿਓ"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"ਹੋਰ ਸੈਟਿੰਗਾਂ"</string>
     <string name="notification_done" msgid="5279426047273930175">"ਹੋ ਗਿਆ"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਸੂਚਨਾ ਕੰਟਰੋਲ"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"ਰੰਗ ਅਤੇ ਵਿਖਾਲਾ"</string>
     <string name="night_mode" msgid="3540405868248625488">"ਰਾਤ ਮੋਡ"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ਡਿਸਪਲੇ ਨੂੰ ਕੈਲੀਬ੍ਰੇਟ ਕਰੋ"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ਬੈਟਰੀ ਸੇਵਰ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ਕਾਰਗੁਜ਼ਾਰੀ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਡੈਟੇ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"ਬਟਨ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ਸਿਸਟਮ"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ਹਾਲੀਆ"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ਉੱਪਰ ਲੈ ਜਾਓ"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ਖੱਬੇ ਲੈ ਜਾਓ"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"ਸੱਜੇ ਲੈ ਜਾਓ"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings_tv.xml b/packages/SystemUI/res/values-pa-rIN/strings_tv.xml
index 78a5322..7cbda258 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP ਕੰਟਰੋਲ ਕਰਨ ਲਈ "<b>"ਹੋਮ"</b>" ਦਬਾਈ ਰੱਖੋ"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP ਨੂੰ ਕੰਟਰੋਲ ਕਰਨ ਲਈ ਹੋਮ ਬਟਨ ਨੂੰ ਦੱਬੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"ਸਮਝ ਲਿਆ"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"ਖ਼ਾਰਜ ਕਰੋ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 12452f6..bb8f200 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -238,8 +238,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Prośby o lokalizację są aktywne"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ustawienia powiadomień"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ustawienia aplikacji <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran zostanie obrócony automatycznie."</string>
@@ -312,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nie udało się uruchomić aplikacji <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacja <xliff:g id="APP">%s</xliff:g> została wyłączona w trybie bezpiecznym."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Wyczyść"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Wyczyść wszystko"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ta aplikacja nie obsługuje trybu wielu okien"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacja nie obsługuje trybu wielu okien"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podziel poziomo"</string>
@@ -482,8 +480,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Pokazuj na początku listy powiadomień, wyświetlaj na ekranie i sygnalizuj dźwiękiem"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Więcej ustawień"</string>
     <string name="notification_done" msgid="5279426047273930175">"Gotowe"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> – ustawienia powiadomień"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Kolor i wygląd"</string>
     <string name="night_mode" msgid="3540405868248625488">"Tryb nocny"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibracja wyświetlacza"</string>
@@ -503,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Oszczędzanie baterii nie jest dostępne podczas ładowania"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Oszczędzanie baterii"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Zmniejsza wydajność i ogranicza dane w tle"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Przycisk <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Wstecz"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"W górę"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"W dół"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"W lewo"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"W prawo"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Do środka"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Spacja"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Odtwórz/wstrzymaj"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zatrzymaj"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Następny"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Poprzedni"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Przewiń do tyłu"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Przewiń do przodu"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Klawiatura numeryczna <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekran główny"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Ostatnie"</string>
@@ -561,4 +584,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Przesuń w górę"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Przesuń w lewo"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Przesuń w prawo"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacja może nie działać w trybie wielu okien"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml
index 78bb18e..70be3d9 100644
--- a/packages/SystemUI/res/values-pl/strings_tv.xml
+++ b/packages/SystemUI/res/values-pl/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Przytrzymaj "<b>"EKRAN GŁÓWNY"</b>", by sterować PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Przytrzymaj przycisk EKRAN GŁÓWNY, by sterować PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Zamknij"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 10d3181..dd9fbf0 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configurações de notificação"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configurações de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Este app não é compatível com o modo de várias janelas"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"O app não é compatível com o modo de várias janelas"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificações, mostrar parcialmente na tela e permitir sons"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Mais configurações"</string>
     <string name="notification_done" msgid="5279426047273930175">"Concluído"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Controles de notificação do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Cor e aparência"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modo noturno"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrar tela"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Voltar"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Para cima"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Para baixo"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Para a esquerda"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Para a direita"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centralizar"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Barra de espaço"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproduzir/pausar"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Parar"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Avançar"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retroceder"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avançar rapidamente"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover para cima"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover para a esquerda"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover para a direita"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
index 6061af3..0827f9c7 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Mantenha a tecla \"HOME\" pressionada para controlar o PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Dispensar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 7a2866d..a700215 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Pedidos de localização ativos"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Definições de notificação"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Definições do <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"O ecrã será rodado automaticamente."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar o <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Esta aplicação não é compatível com várias janelas"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"A aplicação não é compatível com várias janelas"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificações, mostrar no ecrã e permitir som"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Mais definições"</string>
     <string name="notification_done" msgid="5279426047273930175">"Concluído"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Controlos de notificações do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Cor e aspeto"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modo noturno"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrar ecrã"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Poupança de bateria não disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Poupança de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados de segundo plano"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Início"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Anterior"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Para cima"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Para baixo"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Para a esquerda"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Para a direita"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Ao centro"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulação"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Espaço"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retrocesso"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproduzir/interromper"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Parar"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Seguinte"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Recuar"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avançar"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Página para cima"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Página para baixo"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Eliminar"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Início"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fim"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Inserir"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Teclado numérico <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Página inicial"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover para cima"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover para a esquerda"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover para a direita"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
index 78d1352..2f465d2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Prima sem soltar o botão "<b>"HOME"</b>" para controlar o PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Prima sem soltar o botão HOME para controlar o PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Compreendi"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 10d3181..dd9fbf0 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configurações de notificação"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configurações de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Este app não é compatível com o modo de várias janelas"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"O app não é compatível com o modo de várias janelas"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Mostrar na parte superior da lista de notificações, mostrar parcialmente na tela e permitir sons"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Mais configurações"</string>
     <string name="notification_done" msgid="5279426047273930175">"Concluído"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Controles de notificação do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Cor e aparência"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modo noturno"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrar tela"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Botão <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Voltar"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Para cima"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Para baixo"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Para a esquerda"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Para a direita"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centralizar"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Barra de espaço"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Reproduzir/pausar"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Parar"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Avançar"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Anterior"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Retroceder"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Avançar rapidamente"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistema"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover para cima"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover para a esquerda"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover para a direita"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml
index 6061af3..0827f9c7 100644
--- a/packages/SystemUI/res/values-pt/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Mantenha a tecla \"HOME\" pressionada para controlar o PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Dispensar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5f71c41..353f11c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -237,8 +237,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Locație setată prin GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitări locație active"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeți toate notificările."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Setări pentru notificări"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Setări <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
@@ -311,8 +310,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"căutare"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nu a putut porni."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplicația <xliff:g id="APP">%s</xliff:g> este dezactivată în modul sigur."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Istoric"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ștergeți"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ștergeți-le pe toate"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Această aplicație nu acceptă ferestre multiple"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplicația nu acceptă ferestre multiple"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divizare pe orizontală"</string>
@@ -481,8 +479,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Apar în partea de sus a listei cu notificări, se afișează pentru scurt timp pe ecran și se permite un sunet"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Mai multe setări"</string>
     <string name="notification_done" msgid="5279426047273930175">"Terminat"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Opțiuni privind notificările pentru <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Culoare și aspect"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modul Noapte"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Calibrați afișarea"</string>
@@ -502,6 +499,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Economisirea bateriei nu este disponibilă pe durata încărcării"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economisirea bateriei"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce performanța și datele de fundal"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Butonul <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"La început"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Înapoi"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"În sus"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"În jos"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"La stânga"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"La dreapta"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"În centru"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Spațiu"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Redați/Întrerupeți"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Opriți"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Înainte"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Înapoi"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Derulați înapoi"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Derulați rapid înainte"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"O pagină mai sus"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"O pagină mai jos"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Ștergeți"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"La început"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"La final"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Inserați"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tasta numerică <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ecran de pornire"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recente"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mutați în sus"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mutați spre stânga"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mutați spre dreapta"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml
index fcbfd07..9ef90dd 100644
--- a/packages/SystemUI/res/values-ro/strings_tv.xml
+++ b/packages/SystemUI/res/values-ro/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Apăsați lung "<b>"ACASĂ"</b>" pentru a controla PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Apăsați lung butonul ECRAN DE PORNIRE pentru a controla PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Am înțeles"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Închideți"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ffb0a73..26d936a 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -238,8 +238,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Координаты по GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Есть активные запросы на определение местоположения"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Настройки уведомлений"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Настройки приложения \"<xliff:g id="APP_NAME">%s</xliff:g>\""</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран будет поворачиваться автоматически."</string>
@@ -312,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не удалось запустить приложение \"<xliff:g id="APP">%s</xliff:g>\""</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" отключено в безопасном режиме."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Журнал"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Очистить"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Очистить все"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Приложение не поддерживает многооконный режим"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Приложение не поддерживает многооконный режим"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Разделить по горизонтали"</string>
@@ -482,8 +480,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Показывать со звуком в начале списка уведомлений и поверх всех окон"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Другие настройки"</string>
     <string name="notification_done" msgid="5279426047273930175">"Готово"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Управление оповещениями (<xliff:g id="APP_NAME">%1$s</xliff:g>)"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Цвета и стиль"</string>
     <string name="night_mode" msgid="3540405868248625488">"Ночной режим"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Калибровка дисплея"</string>
@@ -503,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим энергосбережения нельзя включить во время зарядки"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим энергосбережения"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ограничивает производительность и фоновую передачу данных"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Главный экран"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Стрелка вверх"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Стрелка вниз"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Стрелка влево"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Стрелка вправо"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Центральная стрелка"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Пробел"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Ввод"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Воспроизведение/пауза"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Стоп"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Далее"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Назад"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Перемотка назад"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Перемотка вперед"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Цифровая клавиатура <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Система"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Главный экран"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавние"</string>
@@ -561,4 +584,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Поднять"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Сдвинуть влево"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Сдвинуть вправо"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Приложение не поддерживает многооконный режим"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml
index 309ce73..027cb1f 100644
--- a/packages/SystemUI/res/values-ru/strings_tv.xml
+++ b/packages/SystemUI/res/values-ru/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Управляйте кадром в кадре, удерживая кнопку "<b>"ГЛАВНАЯ"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Управляйте режимом \"Кадр в кадре\", удерживая кнопку ГЛАВНАЯ"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"ОК"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Закрыть"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 84c2f1b..b47af0d 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS මඟින් ස්ථානය සකසා ඇත"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"පිහිටීම් ඉල්ලීම් සක්‍රියයි"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"සියලු දැනුම්දීම් හිස් කරන්න."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"දැනුම්දීම් සැකසීම්"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> සැකසීම්"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"තිරය ස්වයංක්‍රීයව කරකැවේ."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"සෙවීම"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කළ නොහැක."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ආරක්ෂිත ප්‍රකාරය තුළ අබලයි."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ඉතිහාසය"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"හිස් කරන්න"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"සියල්ල හිස් කරන්න"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"මෙම යෙදුම බහු-කවුළුව සඳහා සහාය නොදක්වයි"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"යෙදුම බහු-කවුළුව සඳහා සහාය නොදක්වයි"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"තිරස්ව වෙන් කරන්න"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"දැනුම්දීම් ලැයිස්තුවෙහි ඉහළින්ම පෙන්වන්න, තිරයට එබිකම් කර ශබ්දයට ඉඩ දෙන්න"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"තව සැකසීම්"</string>
     <string name="notification_done" msgid="5279426047273930175">"නිමයි"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> දැනුම්දීම් පාලන"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"වර්ණය සහ පෙනුම"</string>
     <string name="night_mode" msgid="3540405868248625488">"රාත්‍රී ප්‍රකාරය"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"සංදර්ශකය ක්‍රමාංකනය කරන්න"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ආරෝපණය අතරතුර බැටරි සුරැකුම ලබා ගත නොහැකිය."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"බැටරි සුරැකුම"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ක්‍රියාකාරිත්වය සහ පසුබිම් දත්ත අඩු කරන්න"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> බොත්තම"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home යතුර"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"ආපසු"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"උඩු"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"යටි"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"වම්"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"දකුණු"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"මැද"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab යතුර"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"ඉඩ යතුර"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter යතුර"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace යතුර"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ධාවනය කරන්න/විරාම කරන්න"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"නතර කරන්න"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"ඊළඟ"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"පෙර"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"නැවත ඔතන්න"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"වේගයෙන් ඉදිරියට යන"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up යතුර"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down යතුර"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete යතුර"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home යතුර"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End යතුර"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert යතුර"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock යතුර"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> අංක පෑඩය"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"පද්ධතිය"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"මුල් පිටුව"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"මෑත"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"ඉහළට ගෙන යන්න"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"වමට ගෙන යන්න"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"දකුණට ගෙන යන්න"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"යෙදුම බහු-කවුළුව සමඟ ක්‍රියා නොකළ හැකිය."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings_tv.xml b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
index f3e95a1..3380754 100644
--- a/packages/SystemUI/res/values-si-rLK/strings_tv.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP පාලනයට "<b>"HOME"</b>" අල්ලාගන්න"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP පාලනය කිරීමට HOME බොත්තම ඔබා අල්ලාගෙන සිටින්න"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"හරි, තේරුණා"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"අස් කරන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index e53b037..6c3b477 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -238,8 +238,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Žiadosti o polohu sú aktívne"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Nastavenia upozornení"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Nastavenia aplikácie <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka sa automaticky otočí."</string>
@@ -312,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikáciu <xliff:g id="APP">%s</xliff:g> sa nepodarilo spustiť"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikácia <xliff:g id="APP">%s</xliff:g> je v núdzovom režime zakázaná."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"História"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vymazať"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vymazať všetko"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Táto aplikácia nepodporuje režim viacerých okien"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikácia nepodporuje režim viacerých okien"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Rozdeliť vodorovné"</string>
@@ -482,8 +480,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Zobrazovať v hornej časti zoznamu upozornení, zobrazovať cez obrazovku a povoliť zvukový signál"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Ďalšie nastavenia"</string>
     <string name="notification_done" msgid="5279426047273930175">"Hotovo"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Ovládacie prvky pre upozornenia z aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Farba a vzhľad"</string>
     <string name="night_mode" msgid="3540405868248625488">"Nočný režim"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibrovať obrazovku"</string>
@@ -503,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Počas nabíjania nie je Šetrič batérie k dispozícii"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Šetrič batérie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Obmedzí výkonnosť a údaje na pozadí"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Tlačidlo <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Domov"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Späť"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Nahor"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Nadol"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Doľava"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Doprava"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Do stredu"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulátor"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Medzerník"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Prehrať/pozastaviť"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Zastaviť"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Nasledujúce"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Predchádzajúce"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Pretočiť späť"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Pretočiť dopredu"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Posunúť o stranu vyššie"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Posunúť o stranu nižšie"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Odstrániť"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Domov"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Ukončiť"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Vložiť"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Číselná klávesnica <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Systém"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Domovská stránka"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedávne"</string>
@@ -561,4 +584,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Posunúť nahor"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Posunúť doľava"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Posunúť doprava"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml
index 64fa0e8..cc48e07 100644
--- a/packages/SystemUI/res/values-sk/strings_tv.xml
+++ b/packages/SystemUI/res/values-sk/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Režim PIP ovládajte pomocou tlačidla "<b>"PLOCHA"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Režim PIP ovládajte stlačením a podržaním tlačidla PLOCHA"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Dobre"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Odmietnuť"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8cff73b1..359c909 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -238,8 +238,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Aktivne zahteve za lokacijo"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"in <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Nastavitve obvestil"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Nastavitve aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
@@ -312,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacije <xliff:g id="APP">%s</xliff:g> ni bilo mogoče zagnati."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je v varnem načinu onemogočena."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Zgodovina"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Izbriši"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Izbriši vse"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ta aplikacija ne podpira načina z več okni"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacija ne podpira načina z več okni"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Razdeli vodoravno"</string>
@@ -482,8 +480,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Prikaži na vrhu seznama obvestil, za hip pokaži predogled na zaslonu in dovoli zvok"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Več nastavitev"</string>
     <string name="notification_done" msgid="5279426047273930175">"Dokončano"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrolniki obvestil za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Barva in videz"</string>
     <string name="night_mode" msgid="3540405868248625488">"Nočni način"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Umerjanje zaslona"</string>
@@ -503,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Varčevanje z energijo akumulatorja med polnjenjem ni na voljo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Varčevanje z energijo akumulatorja"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omeji zmogljivost delovanja in prenos podatkov v ozadju"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Gumb <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Začetek"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Nazaj"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Gor"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Dol"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Levo"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Desno"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Sredina"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Zavihek"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Preslednica"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Vnesi"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Premik nazaj"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Predvajaj/zaustavi"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Ustavi"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Naslednji"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prejšnji"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Previj nazaj"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Previj naprej"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Stran gor"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Stran dol"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Izbriši"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Začetek"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Konec"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Vstavi"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Številska tipkovnica <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Začetni zaslon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni"</string>
@@ -561,4 +584,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Premakni navzgor"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Premakni levo"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Premakni desno"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacija morda ne deluje v načinu z več okni"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml
index 4d0576b..38f9e8e3 100644
--- a/packages/SystemUI/res/values-sl/strings_tv.xml
+++ b/packages/SystemUI/res/values-sl/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Pridr. "<b>"HOME"</b>" za up. n. PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Pridržite gumb HOME za upravljanje načina PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Razumem"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Opusti"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 35b4dc7..2448a4ae 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Vendndodhja është caktuar nga GPS-ja"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Kërkesat për vendodhje janë aktive"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Pastro të gjitha njoftimet."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Cilësimet e njoftimeve"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Cilësimet e <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrani do të rrotullohet automatikisht."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"kërko"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nuk mundi të nisej."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> është i çaktivizuar në modalitetin e sigurt."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historiku"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Pastro"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Pastroji të gjitha"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ky aplikacion nuk e mbështet modalitetin me shumë dritare"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Aplikacioni nuk e mbështet modalitetin me shumë dritare"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Ndaje horizontalisht"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Shfaqi në krye të listës së njoftimeve, shfaq vështrim të shpejtë në ekran dhe lësho një tingull"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Cilësime të tjera"</string>
     <string name="notification_done" msgid="5279426047273930175">"U krye"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Kontrollet e njoftimeve të <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Ngjyra dhe pamja"</string>
     <string name="night_mode" msgid="3540405868248625488">"Modaliteti i natës"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibro ekranin"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"\"Kursyesi i baterisë\" nuk është i disponueshëm gjatë karikimit"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kursyesi i baterisë"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Pakëson veprimtarinë dhe të dhënat në sfond"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Butoni <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Kreu"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Prapa"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Lart"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Poshtë"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Majtas"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Djathtas"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Qendror"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Skedë"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Hapësirë"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Kthim prapa"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Luaj/pauzë"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Ndalo"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Përpara"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Prapa"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rikthe me shpejtësi"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Përparo me shpejtësi"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Faqja lart"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Faqja poshtë"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Fshi"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Kreu"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Fundi"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Fut"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Kyçja e numrave"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Tastiera numerike <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistemi"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Kreu"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Të fundit"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Lëviz lart"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Lëviz majtas"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Lëviz djathtas"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Aplikacioni mund të mos punojë me funksionin me shumë dritare."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
index bcb53fc..672a119 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Mbaj shtypur "<b>"HOME"</b>" për të kontrolluar PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Shtyp dhe mbaj shtypur butonin HOME për të kontrolluar PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"E kuptova"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Hiqe"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5bc07fa..a2a61db7 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -237,8 +237,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Локацију је подесио GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Има активних захтева за локацију"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"и још <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Подешавања обавештења"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Подешавања за <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран ће се аутоматски ротирати."</string>
@@ -311,8 +310,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Покретање апликације <xliff:g id="APP">%s</xliff:g> није успело."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Апликација <xliff:g id="APP">%s</xliff:g> је онемогућена у безбедном режиму."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Историја"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Обриши"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Обриши све"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ова апликација не подржава режим са више прозора"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Апликација не подржава режим са више прозора"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Подели хоризонтално"</string>
@@ -481,8 +479,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Приказују се у врху листе обавештења, накратко се приказују на екрану и емитују звук"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Још подешавања"</string>
     <string name="notification_done" msgid="5279426047273930175">"Готово"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Контроле обавештења за апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Боја и изглед"</string>
     <string name="night_mode" msgid="3540405868248625488">"Ноћни режим"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Калибришите екран"</string>
@@ -502,6 +499,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Уштеда батерије није доступна током пуњења"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Уштеда батерије"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Смањује перформансе и позадинске податке"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Дугме <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Тастер Почетна"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Тастер Назад"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Тастер са стрелицом нагоре"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Тастер са стрелицом надоле"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Тастер са стрелицом налево"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Тастер са стрелицом надесно"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Тастер са централном стрелицом"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Табулатор"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Тастер за размак"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Тастер за брисање уназад"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Тастер за репродукцију/паузирање"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Тастер за заустављање"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Тастер Следећа"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Тастер Претходна"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Тастер за премотавање уназад"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Тастер за премотавање унапред"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Тастер за страницу нагоре"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Тастер за страницу надоле"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Тастер за брисање"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Тастер Почетна"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Тастер за крај"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Тастер за уметање"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Тастер <xliff:g id="NAME">%1$s</xliff:g> на нумеричкој тастатури"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Систем"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетни"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавни садржај"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Помери нагоре"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Помери улево"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Помери удесно"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml
index a92374f..d822e4e 100644
--- a/packages/SystemUI/res/values-sr/strings_tv.xml
+++ b/packages/SystemUI/res/values-sr/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109"><b>"ПОЧЕТНИ ЕКРАН"</b>" конт. PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Притисните и задржите дугме ПОЧЕТНИ ЕКРАН да бисте контролисали PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Важи"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Одбаци"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7e40ce0..a78841c 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Det finns aktiva platsbegäranden"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> till"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Aviseringsinställningar"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Inställningar för <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Det gick inte att starta appen <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> är inaktiverad i säkert läge."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historik"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Rensa"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Rensa alla"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Den här appen har inte stöd för flera fönster"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Appen har inte stöd för flera fönster"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dela horisontellt"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Visa högst upp i aviseringslistan och med snabbtitt på skärmen samt tillåt ljud"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Fler inställningar"</string>
     <string name="notification_done" msgid="5279426047273930175">"Klar"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Inställningar för <xliff:g id="APP_NAME">%1$s</xliff:g>-aviseringar"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Färg och utseende"</string>
     <string name="night_mode" msgid="3540405868248625488">"Nattläge"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Kalibrera skärmen"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparläget är inte tillgängligt vid laddning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparläge"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Minskar prestanda och bakgrundsdata"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Knappen <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Start"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Tillbaka"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Upp"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Ned"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Vänster"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Höger"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centrera"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Flik"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Blanksteg"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Retur"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backsteg"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Spela upp/Pausa"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Avsluta"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Nästa"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Föregående"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Spola tillbaka"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Snabbspola framåt"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Sida upp"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Sida ned"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Radera"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Start"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Slut"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Infoga"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numeriskt tangentbord <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startsida"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Senaste"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Flytta uppåt"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Flytta åt vänster"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Flytta åt höger"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Appen fungerar eventuellt inte i flerfönsterläge"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml
index 790ef76..0c0afc3 100644
--- a/packages/SystemUI/res/values-sv/strings_tv.xml
+++ b/packages/SystemUI/res/values-sv/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Styr PIP med "<b>"startknappen"</b></string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Styr bild-i-bild genom att hålla ned startsideknappen"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ignorera"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index aa9ed8a..7351edc 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Maombi ya eneo yanatumika"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Mipangilio ya arifa"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Mipangilio ya <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Haikuweza kuanzisha <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> imezimwa katika hali salama."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Futa"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Futa zote"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Programu hii haitumiki katika hali ya madirisha mengi"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Programu haitumiki katika hali ya madirisha mengi"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gawanya Mlalo"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Onyesha katika sehemu ya juu ya orodha ya arifa, chungulia kwenye skrini na uruhusu sauti"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Mipangilio zaidi"</string>
     <string name="notification_done" msgid="5279426047273930175">"Nimemaliza"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Vidhibiti vya arifa za <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Rangi na mwonekano"</string>
     <string name="night_mode" msgid="3540405868248625488">"Hali ya usiku"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Rekebisha onyesho"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Kiokoa Betri hakipatikani unapochaji betri"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kiokoa Betri"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Hupunguza data ya chini chini na utendaji"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Kitufe cha <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Nyuma"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Juu"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Chini"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Kushoto"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Kulia"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Katikati"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Cheza/Sitisha"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Simamisha"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Inayofuata"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Iliyotangulia"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rudisha nyuma"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Sogeza mbele Haraka"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Mfumo"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Mwanzo"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Zilizotumika majuzi"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Sogeza juu"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sogeza kushoto"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sogeza kulia"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml
index bd29705..4875f73 100644
--- a/packages/SystemUI/res/values-sw/strings_tv.xml
+++ b/packages/SystemUI/res/values-sw/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Shikilia kitufe cha "<b>"HOME"</b>" ili udhibiti PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Bonyeza na ushikilie kitufe cha HOME ili kudhibiti PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Nimeelewa"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Ondoa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index db4da10..1f6bbd3 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -33,16 +33,6 @@
     <!-- Set to true to enable the user switcher on the keyguard. -->
     <bool name="config_keyguardUserSwitcher">true</bool>
 
-    <!-- Recents: The relative range of visible tasks from the current scroll position
-         while the stack is focused. -->
-    <item name="recents_layout_focused_range_min" format="float" type="integer">-3</item>
-    <item name="recents_layout_focused_range_max" format="float" type="integer">3</item>
-
-    <!-- Recents: The relative range of visible tasks from the current scroll position
-         while the stack is not focused. -->
-    <item name="recents_layout_unfocused_range_min" format="float" type="integer">-2</item>
-    <item name="recents_layout_unfocused_range_max" format="float" type="integer">2.5</item>
-
     <!-- Nav bar button default ordering/layout -->
     <string name="config_navBarLayout" translatable="false">space;back,home,recent;menu_ime</string>
 
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 66963c4..a2010be 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -96,15 +96,6 @@
 
     <dimen name="qs_expand_margin">0dp</dimen>
 
-    <!-- The top padding for the task stack. -->
-    <dimen name="recents_stack_top_padding">40dp</dimen>
-
-    <!-- The size of the initial peek area at the bottom of the stack (above the nav bar). -->
-    <dimen name="recents_initial_bottom_peek_size">100dp</dimen>
-
-    <!-- The side padding for the task stack. -->
-    <dimen name="recents_stack_left_right_padding">64dp</dimen>
-
     <!-- Keyboard shortcuts helper -->
     <dimen name="ksh_layout_width">488dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 8fe6be9..25e96c8 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -29,11 +29,6 @@
     <!-- Bottom margin (from display edge) for status bar panels -->
     <dimen name="panel_float">56dp</dimen>
 
-    <!-- The radius of the rounded corners on a task view. -->
-    <dimen name="recents_task_view_rounded_corners_radius">3dp</dimen>
-    <!-- The radius of the rounded corners on a task view's shadow. -->
-    <dimen name="recents_task_view_shadow_rounded_corners_radius">12dp</dimen>
-
     <!-- 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. -->
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 3eb7565..cfa587b 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS அமைத்த இருப்பிடம்"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"இருப்பிடக் கோரிக்கைகள் இயக்கப்பட்டன"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"எல்லா அறிவிப்புகளையும் அழி."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"அறிவிப்பு அமைப்புகள்"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> அமைப்புகள்"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"திரை தானாகச் சுழலும்."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"தேடு"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ஐத் தொடங்க முடியவில்லை."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"பாதுகாப்புப் பயன்முறையில் <xliff:g id="APP">%s</xliff:g> முடக்கப்பட்டது."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"வரலாறு"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"அழி"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"அனைத்தையும் அழி"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"இந்தப் பயன்பாடு பல சாளர அம்சத்தை ஆதரிக்கவில்லை"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"பயன்பாடு பல சாளர அம்சத்தை ஆதரிக்காது"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"கிடைமட்டமாகப் பிரி"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"அறிவிப்புகள் பட்டியலின் மேற்பகுதியில், சில வினாடிகளுக்கு ஒலியுடன் திரையில் காட்டு"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"மேலும் அமைப்புகள்"</string>
     <string name="notification_done" msgid="5279426047273930175">"முடிந்தது"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> அறிவிப்புக் கட்டுப்பாடுகள்"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"வண்ணமும் தோற்றமும்"</string>
     <string name="night_mode" msgid="3540405868248625488">"இரவுப் பயன்முறை"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"திரையை அளவுத்திருத்தம் செய்"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"சார்ஜ் செய்யும் போது பேட்டரி சேமிப்பானைப் பயன்படுத்த முடியாது"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"பேட்டரி சேமிப்பான்"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"செயல்திறனையும் பின்புலத்தில் தரவு செயலாக்கப்படுவதையும் குறைக்கும்"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> பொத்தான்"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"ஹோம்"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"பேக்"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"மேலே"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"கீழே"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"இடது"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"வலது"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"நடு"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"டேப்"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"ஸ்பேஸ்"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"என்டர்"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"பேக்ஸ்பேஸ்"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"பிளே/பாஸ்"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ஸ்டாப்"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"நெக்ஸ்ட்"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ப்ரீவியஸ்"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ரீவைன்ட்"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"ஃபாஸ்ட் பார்வேர்டு"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"பேஜ் அப்"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"பேஜ் டவுன்"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"டெலிட்"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"ஹோம்"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"என்ட்"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"இன்சர்ட்"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"நம்பர் லாக்"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"நம்பர் பேடு <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"முறைமை"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"முகப்பு"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"சமீபத்தியவை"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"மேலே நகர்த்து"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"இடப்புறம் நகர்த்து"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"வலப்புறம் நகர்த்து"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings_tv.xml b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
index e75d86a..7412e27 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIPஐக் கட்டுப்படுத்த, "<b>"முகப்பைப்"</b>" பிடித்திருக்கவும்"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIPஐக் கட்டுப்படுத்த, முகப்புப் பொத்தானை அழுத்திப் பிடிக்கவும்"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"சரி"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"நிராகரி"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 4a6e2d7..b04d074 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"శోధించు"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> సురక్షిత-మోడ్‌లో నిలిపివేయబడింది."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"చరిత్ర"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"తీసివేయి"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"అన్నీ తీసివేయి"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"ఈ అనువర్తనం బహుళ విండోలకు మద్దతు ఇవ్వదు"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"అనువర్తనం బహుళ విండోలకు మద్దతు ఇవ్వదు"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"సమతలంగా విభజించు"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ఛార్జ్ అవుతున్న సమయంలో బ్యాటరీ సేవర్ అందుబాటులో ఉండదు"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"బ్యాటరీ సేవర్"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"పనితీరుని మరియు నేపథ్య డేటాను తగ్గిస్తుంది"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"బటన్ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"వెనుకకు"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"పైకి"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"కిందికి"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ఎడమ"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"కుడి"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"మధ్య"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"అంతరం"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"ప్లే చేయి/పాజ్ చేయి"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"ఆపివేయి"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"తదుపరి"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"మునుపటి"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"రివైండ్ చేయి"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"వేగంగా ఫార్వార్డ్ చేయి"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"నంబర్ ప్యాడ్ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"సిస్టమ్"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"హోమ్"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ఇటీవలివి"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"పైకి తరలించు"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"ఎడమవైపుకు తరలించు"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"కుడివైపుకు తరలించు"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"అనువర్తనం బహుళ విండోల రూపంలో పని చేయకపోవచ్చు"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 33e4346..31e7634 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"คำขอตำแหน่งที่มีการใช้งาน"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"การตั้งค่าการแจ้งเตือน"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"การตั้งค่า <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"หน้าจอจะหมุนโดยอัตโนมัติ"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"ไม่สามารถเริ่มใช้ <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ปิดใช้ในโหมดปลอดภัย"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"ประวัติ"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ล้าง"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ล้างทั้งหมด"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"แอปนี้ไม่สนับสนุนหลายหน้าต่าง"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"แอปไม่สนับสนุนหลายหน้าต่าง"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"แยกในแนวนอน"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"แสดงที่ด้านบนของรายการการแจ้งเตือน แสดงบนหน้าจอและให้ส่งเสียงได้"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"การตั้งค่าเพิ่มเติม"</string>
     <string name="notification_done" msgid="5279426047273930175">"เสร็จสิ้น"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"ส่วนควบคุมการแจ้งเตือนของ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"สีและลักษณะที่ปรากฏ"</string>
     <string name="night_mode" msgid="3540405868248625488">"โหมดกลางคืน"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"ปรับเทียบการแสดงผล"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ไม่สามารถใช้โหมดประหยัดแบตเตอรี่ระหว่างการชาร์จ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"โหมดประหยัดแบตเตอรี่"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ลดประสิทธิภาพการทำงานและข้อมูลแบ็กกราวด์"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"ปุ่ม <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"กลับ"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"ขึ้น"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"ลง"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"ซ้าย"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ขวา"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"กึ่งกลาง"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"แท็บ"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"วรรค"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"ลบถอยหลัง"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"เล่น/หยุดชั่วคราว"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"หยุด"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"ถัดไป"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"ก่อนหน้า"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"กรอกลับ"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"กรอไปข้างหน้า"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"เลื่อนหน้าขึ้น"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"เลื่อนหน้าลง"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"ลบ"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"แทรก"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"แผงตัวเลข <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"ระบบ"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"หน้าแรก"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ล่าสุด"</string>
@@ -560,4 +583,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"เลื่อนขึ้น"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"เลื่อนไปทางซ้าย"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"เลื่อนไปทางขวา"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"แอปอาจทำงานกับหลายหน้าต่างไม่ได้"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
index b43078d..d7b26687 100644
--- a/packages/SystemUI/res/values-th/strings_tv.xml
+++ b/packages/SystemUI/res/values-th/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"กด "<b>"HOME"</b>" ค้างไว้เพื่อควบคุม PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"กดปุ่ม HOME ค้างไว้เพื่อควบคุม PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"รับทราบ"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"ปิด"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 61eaa9d..c144b9b 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasyong itinatakda ng GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Aktibo ang mga kahilingan ng lokasyon"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Mga setting ng notification"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Mg setting ng <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Awtomatikong iikot ang screen."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Hindi masimulan <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Naka-disable ang <xliff:g id="APP">%s</xliff:g> sa safe-mode."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"I-clear"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"I-clear lahat"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Hindi sinusuportahan ng app na ito ang multi-window"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Hindi sinusuportahan ng app na ito ang multi-window"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Ipakita sa itaas ng listahan ng mga notification, palitawin sa screen at payagang tumunog"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Higit pang mga setting"</string>
     <string name="notification_done" msgid="5279426047273930175">"Tapos Na"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Mga kontrol sa notification ng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Kulay at hitsura"</string>
     <string name="night_mode" msgid="3540405868248625488">"Night mode"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"I-calibrate ang display"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Hindi available ang Pangtipid sa Baterya kapag nagcha-charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pangtipid sa Baterya"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Binabawasan ang pagganap at data sa background"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Button na <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Back"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Up"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Down"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Left"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Right"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Center"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Play/Pause"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Stop"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Next"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Previous"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Rewind"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Fast Forward"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"System"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Mga Kamakailang Ginamit"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Ilipat pataas"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Ilipat pakaliwa"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Ilipat pakanan"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Maaaring hindi gumana ang app sa maraming window"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml
index 8d4b1b0ff..74fe314 100644
--- a/packages/SystemUI/res/values-tl/strings_tv.xml
+++ b/packages/SystemUI/res/values-tl/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"I-hold ang "<b>"HOME"</b>" para makontrol ang PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Pindutin nang matagal ang button ng HOME upang makontrol ang PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"I-dismiss"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d5a8b9b..0b40840 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Konum bilgisi istekleri etkin"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildirim ayarları"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ayarları"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran otomatik olarak dönecektir."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlatılamadı."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>, güvenli modda devre dışıdır."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Geçmiş"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Sil"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tümünü temizle"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Bu uygulama, çoklu pencere kullanımını desteklemiyor"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Uygulama, çoklu pencere kullanımını desteklemiyor"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Yatay Ayırma"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Bildirim listesinin üstünde göster, ekrana getir ve sesli bildirime izin ver"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Diğer ayarlar"</string>
     <string name="notification_done" msgid="5279426047273930175">"Bitti"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> bildirim denetimleri"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Renk ve görünüm"</string>
     <string name="night_mode" msgid="3540405868248625488">"Gece modu"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Ekranı kalibre et"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Şarj sırasında Pil Tasarrufu özelliği kullanılamaz"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pil Tasarrufu"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı ve arka plan verilerini azaltır"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> düğmesi"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Geri"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Yukarı"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Aşağı"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Sol"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Sağ"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Orta"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Sekme"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Boşluk"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Geri tuşu"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Oynat/Duraklat"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Durdur"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Sonraki"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Önceki"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Geri Sar"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"İleri Sar"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Sayfa Yukarı"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Sayfa Aşağı"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> Sayısal Tuş Takımı"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ana ekran"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Son çağrılar"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Yukarı taşı"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Sola taşı"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Sağa taşı"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
index a5be6a2..57da7fb 100644
--- a/packages/SystemUI/res/values-tr/strings_tv.xml
+++ b/packages/SystemUI/res/values-tr/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"PIP\'yi kontrol etmek için "<b>"ANA EKRAN"</b>"\'ı basılı tutun"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"PIP\'yi kontrol etmek için ANA EKRAN düğmesini basılı tutun"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Kapat"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 398dea1..d6da864 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -311,8 +311,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не вдалося запустити <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Додаток <xliff:g id="APP">%s</xliff:g> вимкнено в безпечному режимі."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Історія"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Очистити"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Очистити все"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Цей додаток не підтримує багатоекранний режим"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Додаток не підтримує багатоекранний режим"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Розділити горизонтально"</string>
@@ -501,6 +500,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим економії заряду акумулятора недоступний під час заряджання"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим економії заряду акумулятора"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Знижується продуктивність і обмежується обмін даними у фоновому режимі"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Кнопка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Назад"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Стрілка вгору"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Стрілка вниз"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Стрілка вліво"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Стрілка вправо"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Центр"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Пробіл"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Відтворити/призупинити"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Зупинити"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Далі"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Назад"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Перемотати назад"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Перемотати вперед"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Сторінка вгору"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Сторінка вниз"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Система"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Головний екран"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Останні"</string>
@@ -559,4 +584,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Перемістити вгору"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Перемістити ліворуч"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Перемістити праворуч"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Додаток може не працювати в багатовіконному режимі"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 7b5013fe..cc7b8d2 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"‏مقام متعین کیا گیا بذریعہ GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"مقام کی درخواستیں فعال ہیں"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"سبھی اطلاعات صاف کریں۔"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> +"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"اطلاع کی ترتیبات"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ترتیبات"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"اسکرین خود بخود گردش کرے گی۔"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"تلاش کریں"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> کو شروع نہیں کیا جا سکا۔"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"محفوظ موڈ میں <xliff:g id="APP">%s</xliff:g> غیر فعال ہوتی ہے۔"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"سرگزشت"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"صاف کریں"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"سبھی کو صاف کریں"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"یہ ایپ ملٹی ونڈو کی معاونت نہیں کرتی"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"ایپ ملٹی ونڈز کی معاونت نہیں کرتی"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"بلحاظ افقی الگ کریں"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"اطلاعات کی فہرست پر سب سے اوپر دکھائیں، اسکرین پر دکھائیں اور آواز کی اجازت دیں"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"مزید ترتیبات"</string>
     <string name="notification_done" msgid="5279426047273930175">"ہوگیا"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے نوٹیفکیشن کنٹرولز"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"رنگ اور ظہور"</string>
     <string name="night_mode" msgid="3540405868248625488">"رات موڈ"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"نشان زد ڈسپلے"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"چارجنگ کے دوران بیٹری سیور دستیاب نہیں ہے"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بیٹری سیور"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"کارکردگی اور پس منظر کا ڈیٹا کم کر دیتا ہے"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"بٹن <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"پیچھے"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"اوپر"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"نیچے"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"بائیں"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"دائیں"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"سینٹر"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Space"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"چلائیں/موقوف کریں"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"روکیں"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"اگلا"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"گزشتہ"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"ریوائینڈ کریں"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"تیزی سے فارورڈ کریں"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"نمبر پیڈ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"سسٹم"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ہوم"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"حالیہ"</string>
@@ -559,4 +582,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"اوپر منتقل کریں"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"بائیں منتقل کریں"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"دائیں منتقل کریں"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
index aff14b2..78de898 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"‏PIP کنٹرول کرنے کیلئے "<b>"ہوم"</b>" پکڑے رکھیں"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"‏PIP کنٹرول کرنے کیلئے ہوم بٹن دبائیں اور پکڑے رکھیں"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"سمجھ آ گئی"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"برخاست کریں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index bd606c2..eb4f402 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS yordamida manzilni o‘rnatish"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Joylashuv so‘rovlari yoniq"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Barcha eslatmalarni tozalash."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildirishnoma sozlamalari"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> sozlamalari"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik buriladi."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"qidirish"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Xavfsiz rejimda <xliff:g id="APP">%s</xliff:g> ilovasi o‘chirib qo‘yildi."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Jurnal"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tozalash"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Barchasini tozalash"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Bu ilova ko‘p oynali rejimni qo‘llab-quvvatlamaydi"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Bu ilova ko‘p oynali rejimni qo‘llab-quvvatlamaydi"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gorizontal yo‘nalishda bo‘lish"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Bildirishnomalar ro‘yxatining boshida va barcha oynalar ustida ovoz bilan ko‘rsatilsin"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Boshqa sozlamalar"</string>
     <string name="notification_done" msgid="5279426047273930175">"Tayyor"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> bildirishnomalarini boshqarish"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Rang va ko‘rinishi"</string>
     <string name="night_mode" msgid="3540405868248625488">"Tungi rejim"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Ekranni kalibrlash"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Quvvat tejash rejimidan quvvatlash vaqtida foydalanib bo‘lmaydi"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Quvvat tejash rejimi"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Unumdorlik pasayadi va fonda internetdan foydalanish cheklanadi"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> tugmasi"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Bosh ekran"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Orqaga"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Tepaga qaragan ko‘rsatkichli chiziq"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Pastga qaragan ko‘rsatkichli chiziq"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Chapga qaragan ko‘rsatkichli chiziq"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"O‘ngga qaragan ko‘rsatkichli chiziq"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Markaziy ko‘rsatkichli chiziq"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Bo‘sh joy"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Ijro/Pauza"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"To‘xtatish"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Keyingi"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Avvalgi"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Orqaga o‘tkazish"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Oldinga o‘tkazish"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Raqamli tugma: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Tizim"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Bosh ekran"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"So‘nggi ishlatilganlar"</string>
@@ -560,4 +583,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Tepaga siljitish"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Chapga siljitish"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"O‘ngga siljitish"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
index 3a4d176..9300aaa 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"“Kadr ichida kadr” rejimini boshqarish uchun "<b>"BOSHI"</b>" tugmasini bosib turing"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"“Kadr ichida kadr” rejimini boshqarish uchun BOSHIGA tugmasini bosib turing"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Yopish"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index edd0a8b..94eb62f 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Yêu cầu về thông tin vị trí đang hoạt động"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Cài đặt thông báo"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Cài đặt <xliff:g id="APP_NAME">%s</xliff:g>"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Không thể khởi động <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> bị tắt ở chế độ an toàn."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Lịch sử"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Xóa"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Xóa tất cả"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ứng dụng này không hỗ trợ chế độ nhiều cửa sổ"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Ứng dụng không hỗ trợ chế độ nhiều cửa sổ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Phân tách ngang"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Hiển thị ở đầu danh sách thông báo, hiển thị trên màn hình và phát ra âm thanh"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Cài đặt khác"</string>
     <string name="notification_done" msgid="5279426047273930175">"Xong"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"Điều khiển thông báo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Màu sắc và giao diện"</string>
     <string name="night_mode" msgid="3540405868248625488">"Chế độ ban đêm"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Hiệu chỉnh hiển thị"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Trình tiết kiệm pin không khả dụng trong khi sạc"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Trình tiết kiệm pin"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Giảm hiệu suất và dữ liệu nền"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Nút <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Quay lại"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Lên"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Xuống"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Trái"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Phải"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Giữa"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Dấu cách"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Phát/Tạm dừng"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Dừng"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Tiếp theo"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Trước"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Tua lại"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Tua nhanh"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Cuối"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Bàn phím số <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Hệ thống"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Màn hình chính"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Gần đây"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Chuyển lên"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Di chuyển sang trái"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Di chuyển sang phải"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Ứng dụng có thể không hoạt động với nhiều cửa sổ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml
index 7a5e34a..b781503 100644
--- a/packages/SystemUI/res/values-vi/strings_tv.xml
+++ b/packages/SystemUI/res/values-vi/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Giữ "<b>"HOME"</b>" để đ.khiển PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Bấm và giữ nút HOME để điều khiển PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Loại bỏ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 23fb020..614ae70 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"已通过GPS确定位置"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"应用发出了有效位置信息请求"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知设置"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>设置"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
@@ -310,8 +309,8 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"无法启动<xliff:g id="APP">%s</xliff:g>。"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>已在安全模式下停用。"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"历史记录"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
+    <!-- no translation found for recents_stack_action_button_label (6593727103310426253) -->
+    <skip />
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"此应用不支持多窗口模式"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"应用不支持多窗口模式"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -480,8 +479,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"在通知列表顶部显示,同时在屏幕上短暂显示,并允许发出提示音"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"更多设置"</string>
     <string name="notification_done" msgid="5279426047273930175">"完成"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g>通知控件"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"颜色和外观"</string>
     <string name="night_mode" msgid="3540405868248625488">"夜间模式"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"校准显示画面"</string>
@@ -501,6 +499,58 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用节电助手"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"节电助手"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低性能并限制后台流量"</string>
+    <!-- no translation found for keyboard_key_button_template (6230056639734377300) -->
+    <skip />
+    <!-- no translation found for keyboard_key_home (2243500072071305073) -->
+    <skip />
+    <!-- no translation found for keyboard_key_back (2337450286042721351) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_up (5584144111755734686) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (7331518671788337815) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (1346446024676962251) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (3317323247127515341) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_center (2566737770049304658) -->
+    <skip />
+    <!-- no translation found for keyboard_key_tab (3871485650463164476) -->
+    <skip />
+    <!-- no translation found for keyboard_key_space (2499861316311153293) -->
+    <skip />
+    <!-- no translation found for keyboard_key_enter (5739632123216118137) -->
+    <skip />
+    <!-- no translation found for keyboard_key_backspace (1559580097512385854) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_play_pause (3861975717393887428) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_stop (2859963958595908962) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_next (1894394911630345607) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_previous (4256072387192967261) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_rewind (2654808213360820186) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_fast_forward (3849417047738200605) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_up (5654098530106845603) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_down (8720502083731906136) -->
+    <skip />
+    <!-- no translation found for keyboard_key_forward_del (1391451334716490176) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_home (2765693292069487486) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_end (5901174332047975247) -->
+    <skip />
+    <!-- no translation found for keyboard_key_insert (8530501581636082614) -->
+    <skip />
+    <!-- no translation found for keyboard_key_num_lock (5052537581246772117) -->
+    <skip />
+    <!-- no translation found for keyboard_key_numpad_template (8729216555174634026) -->
+    <skip />
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系统"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主屏幕"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
@@ -559,4 +609,6 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"上移"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"左移"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"右移"</string>
+    <!-- no translation found for forced_resizable_info_text (7591061837558867999) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
index 2bfe478..77d3bff 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"按住"<b>"主屏幕"</b>"按钮即可控制画中画功能"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"按住主屏幕按钮即可控制画中画功能"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"知道了"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"关闭"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 902cf71..f5cdcf8 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -309,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」已在安全模式中停用。"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"記錄"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"全部清除"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"此應用程式不支援多視窗模式"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"應用程式不支援多視窗模式"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -499,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用「省電模式」"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"省電模式"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景數據傳輸"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> 鍵"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"返回"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"向上"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"向下"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"向左"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"向右"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"箭咀中心"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"空格"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"輸入 (Enter)"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"播放/暫停"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"停止"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"下一首"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"上一首"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"倒帶"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"向前快轉"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"上一頁"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"下一頁"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"刪除"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"頁面頂端"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"頁面底端"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"插入"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"數字鎖定"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"數字鍵盤 <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近的活動"</string>
@@ -557,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"向上移"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"向左移"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"向右移"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"應用程式可能無法在多重視窗下運作"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index ea32930..fea3cc7 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"有位置資訊要求"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知設定"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>設定"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"螢幕會自動旋轉。"</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」在安全模式中為停用狀態。"</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"紀錄"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"全部清除"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"這個應用程式不支援多視窗模式"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"應用程式不支援多視窗模式"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"顯示在通知清單頂端,同時短暫顯示在畫面上並發出音效"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"更多設定"</string>
     <string name="notification_done" msgid="5279426047273930175">"完成"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」通知控制項"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"顏色和外觀"</string>
     <string name="night_mode" msgid="3540405868248625488">"夜間模式"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"校正顯示畫面"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用節約耗電量模式"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"節約耗電量"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景資料傳輸"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g> 按鈕"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Home 鍵"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"返回"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"向上鍵"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"向下鍵"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"向左鍵"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"向右鍵"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"中央鍵"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab 鍵"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"空格鍵"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Enter 鍵"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace 鍵"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"播放/暫停"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"停止"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"下一個"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"上一個"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"倒轉"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"快轉"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up 鍵"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Page Down 鍵"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Delete 鍵"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Home 鍵"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"End 鍵"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert 鍵"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock 鍵"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"數字鍵 <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"近期活動"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"向上移"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"向左移"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"向右移"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"應用程式可能無法在多視窗模式下運作"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
index a6744e7..4420d87 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"按住「主畫面」"<b></b>"按鈕即可控制子母畫面"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"按住「主畫面」按鈕即可控制子母畫面"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"我知道了"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"關閉"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9f8f298..e94c687 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -236,8 +236,7 @@
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Izicelo zendawo ziyasebenza"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
-    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
-    <skip />
+    <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Izilungiselelo zesaziso"</string>
     <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> izilungiselelo"</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
@@ -310,8 +309,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ayikwazanga ukuqala i-<xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"I-<xliff:g id="APP">%s</xliff:g> ikhutshaziwe kumodi yokuphepha."</string>
-    <string name="recents_history_button_label" msgid="5153358867807604821">"Umlando"</string>
-    <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Sula"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Sula konke"</string>
     <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Lolu hlelo lokusebenza alusekeli amawindi amaningi"</string>
     <string name="recents_launch_non_dockable_task_label" msgid="7862379814938391888">"Uhlelo lokusebenza alusekeli amawindi amaningi"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Hlukanisa okuvundlile"</string>
@@ -480,8 +478,7 @@
     <string name="notification_importance_max" msgid="5806278962376556491">"Bonisa phezulu kohlu lwezaziso, beka phezu kwesikrini futhi uvumele umsindo"</string>
     <string name="notification_more_settings" msgid="816306283396553571">"Izilungiselelo eziningi"</string>
     <string name="notification_done" msgid="5279426047273930175">"Kwenziwe"</string>
-    <!-- no translation found for notification_gear_accessibility (94429150213089611) -->
-    <skip />
+    <string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> izilawuli zasaziso"</string>
     <string name="color_and_appearance" msgid="1254323855964993144">"Umbala nokubonakala"</string>
     <string name="night_mode" msgid="3540405868248625488">"Imodi yasebusuku"</string>
     <string name="calibrate_display" msgid="5974642573432039217">"Sika isibonisi"</string>
@@ -501,6 +498,32 @@
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Isilondolozi sebhethri asitholakali ngesikhathi sokushaja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Isilondolozi sebhethri"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sehlisa ukusebenza nedatha yasemuva"</string>
+    <string name="keyboard_key_button_template" msgid="6230056639734377300">"Inkinobho <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="keyboard_key_home" msgid="2243500072071305073">"Ekhaya"</string>
+    <string name="keyboard_key_back" msgid="2337450286042721351">"Emuva"</string>
+    <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"Phezulu"</string>
+    <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"Phansi"</string>
+    <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Kwesobunxele"</string>
+    <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Kwesokudla"</string>
+    <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Maphakathi"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Ithebhu"</string>
+    <string name="keyboard_key_space" msgid="2499861316311153293">"Isikhala"</string>
+    <string name="keyboard_key_enter" msgid="5739632123216118137">"Faka"</string>
+    <string name="keyboard_key_backspace" msgid="1559580097512385854">"Isikhala"</string>
+    <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Dlala/Misa okwesikhashana"</string>
+    <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Misa"</string>
+    <string name="keyboard_key_media_next" msgid="1894394911630345607">"Okulandelayo"</string>
+    <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Okwangaphambilini"</string>
+    <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Buyisela emuva"</string>
+    <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Iya phambili ngokushesha"</string>
+    <string name="keyboard_key_page_up" msgid="5654098530106845603">"Ikhasi phezulu"</string>
+    <string name="keyboard_key_page_down" msgid="8720502083731906136">"Ikhasi phansi"</string>
+    <string name="keyboard_key_forward_del" msgid="1391451334716490176">"Susa"</string>
+    <string name="keyboard_key_move_home" msgid="2765693292069487486">"Ekhaya"</string>
+    <string name="keyboard_key_move_end" msgid="5901174332047975247">"Phelisa"</string>
+    <string name="keyboard_key_insert" msgid="8530501581636082614">"Faka"</string>
+    <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Izinombolo"</string>
+    <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Phedi yezinombolo <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Isistimu"</string>
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekhaya"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Okwakamuva"</string>
@@ -559,4 +582,5 @@
     <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Iya phezulu"</string>
     <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Iya kwesokunxele"</string>
     <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Iya kwesokudla"</string>
+    <string name="forced_resizable_info_text" msgid="7591061837558867999">"Uhlelo lokusebenza kungenzeka lungasebenzi namawindi amaningi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml
index 5fb063d..1904237 100644
--- a/packages/SystemUI/res/values-zu/strings_tv.xml
+++ b/packages/SystemUI/res/values-zu/strings_tv.xml
@@ -26,6 +26,5 @@
     <string name="pip_hold_home" msgid="340086535668778109">"Bamba "<b>"IKHAYA"</b>" ukuze ulawule i-PIP"</string>
     <string name="pip_onboarding_description" msgid="2882896641362814195">"Cindezela futhi ubambe inkinobho EKHAYA ukuze ulawule i-PIP"</string>
     <string name="pip_onboarding_button" msgid="3957426748484904611">"Ngiyezwa"</string>
-    <!-- no translation found for recents_tv_dismiss (3555093879593377731) -->
-    <skip />
+    <string name="recents_tv_dismiss" msgid="3555093879593377731">"Cashisa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 076ba00..b9aa26b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -63,7 +63,7 @@
     <!-- The recents task bar dark text color to be drawn on top of light backgrounds. -->
     <color name="recents_task_bar_dark_text_color">#cc000000</color>
     <!-- The recents task bar light dismiss icon color to be drawn on top of dark backgrounds. -->
-    <color name="recents_task_bar_light_icon_color">#ffeeeeee</color>
+    <color name="recents_task_bar_light_icon_color">#ccffffff</color>
     <!-- The recents task bar dark dismiss icon color to be drawn on top of light backgrounds. -->
     <color name="recents_task_bar_dark_icon_color">#99000000</color>
     <!-- The lock to task button background color. -->
@@ -151,6 +151,7 @@
 
     <color name="docked_divider_background">#ff000000</color>
     <color name="docked_divider_handle">#ffffff</color>
+    <drawable name="forced_resizable_background">#80000000</drawable>
 
     <color name="default_remote_input_background">@*android:color/notification_default_color</color>
     <color name="remote_input_hint">#99ffffff</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 4e1680d..622ae71 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -86,9 +86,6 @@
 
     <bool name="config_dead_zone_flash">false</bool>
 
-    <!-- Min alpha % that recent items will fade to while being dismissed -->
-    <integer name="config_recent_item_min_alpha">3</integer>
-
     <!-- Whether QuickSettings is in a phone landscape -->
     <bool name="quick_settings_wide">false</bool>
 
@@ -165,9 +162,6 @@
     <!-- The animation duration for subsequent scrolling the stack to a particular item. -->
     <integer name="recents_subsequent_auto_advance_duration">1000</integer>
 
-    <!-- The animation duration for entering and exiting the history. -->
-    <integer name="recents_history_transition_duration">250</integer>
-
     <!-- The delay to enforce between each alt-tab key press. -->
     <integer name="recents_alt_tab_key_delay">200</integer>
 
diff --git a/packages/SystemUI/res/values/config_tv.xml b/packages/SystemUI/res/values/config_tv.xml
new file mode 100644
index 0000000..22b7578
--- /dev/null
+++ b/packages/SystemUI/res/values/config_tv.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
+         when the PIP menu is shown in center. -->
+    <string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string>
+
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
+         when the PIP is shown in Recents without focus. -->
+    <string translatable="false" name="pip_recents_bounds">"800 54 1120 234"</string>
+
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
+         when the PIP is shown in Recents with focus. -->
+    <string translatable="false" name="pip_recents_focused_bounds">"775 54 1145 262"</string>
+</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 8cd2167..d1faa4a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -179,7 +179,8 @@
     <dimen name="qs_date_collapsed_text_size">14sp</dimen>
     <dimen name="qs_date_text_size">16sp</dimen>
     <dimen name="qs_header_gear_translation">16dp</dimen>
-    <dimen name="qs_page_indicator_size">12dp</dimen>
+    <dimen name="qs_page_indicator_width">16dp</dimen>
+    <dimen name="qs_page_indicator_height">8dp</dimen>
     <dimen name="qs_tile_icon_size">24dp</dimen>
     <dimen name="qs_tile_text_size">12sp</dimen>
     <dimen name="qs_tile_divider_height">1dp</dimen>
@@ -234,85 +235,6 @@
     <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
     <dimen name="glowpadview_inner_radius">15dip</dimen>
 
-    <!-- The size of the icon in the recents task view header. -->
-    <dimen name="recents_task_view_header_icon_width">56dp</dimen>
-    <dimen name="recents_task_view_header_icon_height">@dimen/recents_task_bar_height</dimen>
-
-    <!-- The size of a button in the recents task view header. -->
-    <dimen name="recents_task_view_header_button_width">@dimen/recents_task_bar_height</dimen>
-    <dimen name="recents_task_view_header_button_height">@dimen/recents_task_bar_height</dimen>
-
-    <!-- The radius of the rounded corners on a task view. -->
-    <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
-    <!-- The radius of the rounded corners on a task view's shadow. -->
-    <dimen name="recents_task_view_shadow_rounded_corners_radius">12dp</dimen>
-
-    <!-- The min translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_min">3dp</dimen>
-
-    <!-- The max translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_max">24dp</dimen>
-
-    <!-- The amount to translate when animating the removal of a task. -->
-    <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
-
-    <!-- The amount of highlight to make on each task view. -->
-    <dimen name="recents_task_view_highlight">1dp</dimen>
-
-    <!-- The amount to offset when animating into an affiliate group. -->
-    <dimen name="recents_task_view_affiliate_group_enter_offset">32dp</dimen>
-
-    <!-- The height of a task view bar. -->
-    <dimen name="recents_task_bar_height">50dp</dimen>
-
-    <!-- The height of the search bar space. -->
-    <dimen name="recents_search_bar_space_height">64dp</dimen>
-
-    <!-- The overscroll percentage allowed on the stack. -->
-    <item name="recents_stack_overscroll_percentage" format="float" type="dimen">0.0875</item>
-
-    <!-- The top padding for the task stack. -->
-    <dimen name="recents_stack_top_padding">16dp</dimen>
-
-    <!-- The side padding for the task stack. -->
-    <dimen name="recents_stack_left_right_padding">16dp</dimen>
-
-    <!-- The dimesnsions of the dismiss all recents button. -->
-    <dimen name="recents_dismiss_all_button_size">48dp</dimen>
-
-    <!-- The min alpha to apply to a task affiliation group color. -->
-    <item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item>
-
-    <!-- The size of the lock-to-app button. -->
-    <dimen name="recents_lock_to_app_size">56dp</dimen>
-
-    <!-- The size of the lock-to-app button icon. -->
-    <dimen name="recents_lock_to_app_icon_size">28dp</dimen>
-
-    <!-- The amount to allow the stack to overscroll. -->
-    <dimen name="recents_stack_overscroll">24dp</dimen>
-
-    <!-- The size of the initial peek area at the top of the stack (below the status bar). -->
-    <dimen name="recents_initial_top_peek_size">8dp</dimen>
-
-    <!-- The size of the initial peek area at the bottom of the stack (above the nav bar). -->
-    <dimen name="recents_initial_bottom_peek_size">100dp</dimen>
-
-    <!-- The size of the peek area at the top of the stack (below the status bar). -->
-    <dimen name="recents_layout_focused_top_peek_size">@dimen/recents_history_button_height</dimen>
-
-    <!-- The size of each task peek area at the bottom of the stack (above the nav bar). -->
-    <dimen name="recents_layout_focused_bottom_task_peek_size">16dp</dimen>
-
-    <!-- The height of the history button. -->
-    <dimen name="recents_history_button_height">48dp</dimen>
-
-    <!-- The padding between freeform workspace tasks -->
-    <dimen name="recents_freeform_workspace_task_padding">8dp</dimen>
-
-    <!-- The offsets the tasks animate from when recents is launched while docking -->
-    <dimen name="recents_task_view_launched_while_docking_offset">144dp</dimen>
-
     <!-- Space reserved for the cards behind the top card in the bottom stack -->
     <dimen name="bottom_stack_peek_amount">12dp</dimen>
 
@@ -639,4 +561,83 @@
 
     <!-- Keyboard shortcuts helper -->
     <dimen name="ksh_layout_width">@dimen/match_parent</dimen>
+
+<!-- Recents Layout -->
+
+    <!-- The amount to inset the stack, specifically at the top and the other sides.  We also
+         don't want this to change across configurations that Recents can be opened in, so we
+         define them statically for all display sizes. -->
+    <dimen name="recents_layout_min_margin">16dp</dimen>
+    <dimen name="recents_layout_top_margin_phone">16dp</dimen>
+    <dimen name="recents_layout_top_margin_tablet">32dp</dimen>
+    <dimen name="recents_layout_top_margin_tablet_xlarge">40dp</dimen>
+    <dimen name="recents_layout_bottom_margin">16dp</dimen>
+    <dimen name="recents_layout_side_margin_phone">16dp</dimen>
+    <dimen name="recents_layout_side_margin_tablet">48dp</dimen>
+    <dimen name="recents_layout_side_margin_tablet_xlarge">64dp</dimen>
+
+    <!-- The height between the top margin and the top of the focused task. -->
+    <dimen name="recents_layout_top_peek_size">56dp</dimen>
+    <!-- The height between the bottom margin and the top of task in front of the focused task. -->
+    <dimen name="recents_layout_bottom_peek_size">56dp</dimen>
+
+    <!-- The offset from the top and bottom of the stack of the focused task.  The bottom offset
+         will be additionally offset by the bottom system insets since it goes under the nav bar
+         in certain orientations. -->
+    <dimen name="recents_layout_initial_top_offset_phone_port">128dp</dimen>
+    <dimen name="recents_layout_initial_bottom_offset_phone_port">80dp</dimen>
+    <dimen name="recents_layout_initial_top_offset_phone_land">72dp</dimen>
+    <dimen name="recents_layout_initial_bottom_offset_phone_land">72dp</dimen>
+    <dimen name="recents_layout_initial_top_offset_tablet">160dp</dimen>
+    <dimen name="recents_layout_initial_bottom_offset_tablet">112dp</dimen>
+
+    <!-- The min/max translationZ for the tasks in the stack. -->
+    <dimen name="recents_layout_z_min">3dp</dimen>
+    <dimen name="recents_layout_z_max">24dp</dimen>
+
+    <!-- The margin between the freeform and stack.  We also don't want this to change across 
+         configurations that Recents can be opened in, so we define them statically for all 
+         display sizes. -->
+    <dimen name="recents_freeform_layout_bottom_margin">16dp</dimen>
+
+    <!-- The padding between each freeform task. -->
+    <dimen name="recents_freeform_layout_task_padding">8dp</dimen>
+
+<!-- Recents Views -->
+
+    <!-- The height of a task view bar.  This has to be large enough to cover the action bar
+         height in either orientation at this smallest width. -->
+    <dimen name="recents_task_view_header_height">56dp</dimen>
+    <dimen name="recents_task_view_header_height_tablet_land">64dp</dimen>
+
+    <!-- The padding of a button in the recents task view header. -->
+    <dimen name="recents_task_view_header_button_padding">16dp</dimen>
+    <dimen name="recents_task_view_header_button_padding_tablet_land">20dp</dimen>
+
+    <!-- The radius of the rounded corners on a task view and its shadow (which can be larger
+         to create a softer corner effect. -->
+    <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
+    <dimen name="recents_task_view_shadow_rounded_corners_radius">6dp</dimen>
+
+    <!-- The amount of highlight to make on each task view. -->
+    <dimen name="recents_task_view_highlight">1dp</dimen>
+
+    <!-- The size of the lock-to-app button and its icon. -->
+    <dimen name="recents_lock_to_app_size">56dp</dimen>
+    <dimen name="recents_lock_to_app_icon_size">28dp</dimen>
+
+    <!-- The amount of overscroll allowed when flinging to the end of the stack. -->
+    <dimen name="recents_fling_overscroll_distance">24dp</dimen>
+
+    <!-- The min alpha to apply to a task affiliation group color. -->
+    <item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item>
+
+    <!-- The amount to offset when animating into an affiliate group. -->
+    <dimen name="recents_task_stack_animation_affiliate_enter_offset">32dp</dimen>
+
+    <!-- The offsets the tasks animate from when recents is launched while docking -->
+    <dimen name="recents_task_stack_animation_launched_while_docking_offset">144dp</dimen>
+
+    <!-- The amount to translate when animating the removal of a task. -->
+    <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/integers_tv.xml b/packages/SystemUI/res/values/integers_tv.xml
index c60c245..20cd330 100644
--- a/packages/SystemUI/res/values/integers_tv.xml
+++ b/packages/SystemUI/res/values/integers_tv.xml
@@ -17,4 +17,5 @@
     <integer name="item_scale_anim_duration">150</integer>
     <integer name="dismiss_short_duration">200</integer>
     <integer name="dismiss_long_duration">400</integer>
-</resources>
\ No newline at end of file
+    <integer name="recents_tv_pip_focus_anim_duration">200</integer>
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 091ba51..a523a41 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -731,10 +731,8 @@
     <string name="recents_launch_error_message">Could not start <xliff:g id="app" example="Calendar">%s</xliff:g>.</string>
     <!-- Recents: Launch disabled string. [CHAR LIMIT=NONE] -->
     <string name="recents_launch_disabled_message"><xliff:g id="app" example="Calendar">%s</xliff:g> is disabled in safe-mode.</string>
-    <!-- Recents: Show history string. [CHAR LIMIT=NONE] -->
-    <string name="recents_history_button_label">History</string>
-    <!-- Recents: History clear all string. [CHAR LIMIT=NONE] -->
-    <string name="recents_history_clear_all_button_label">Clear</string>
+    <!-- Recents: Stack action button string. [CHAR LIMIT=NONE] -->
+    <string name="recents_stack_action_button_label">Clear all</string>
     <!-- Recents: Non-dockable task drag message. [CHAR LIMIT=NONE] -->
     <string name="recents_drag_non_dockable_task_message">This app does not support multi-window</string>
     <!-- Recents: Non-dockable task launch sub header. [CHAR LIMIT=NONE] -->
@@ -1329,6 +1327,59 @@
     <!-- Summary of switch for battery saver [CHAR LIMIT=NONE] -->
     <string name="battery_detail_switch_summary">Reduces performance and background data</string>
 
+    <!-- Name used for certain Keyboard keys on gamepads, e.g. "Button L1". -->
+    <string name="keyboard_key_button_template">Button <xliff:g id="name">%1$s</xliff:g></string>
+    <!-- Name used to refer to the "Home" key on the keyboard. -->
+    <string name="keyboard_key_home">Home</string>
+    <!-- Name used to refer to the "Back" key on the keyboard. -->
+    <string name="keyboard_key_back">Back</string>
+    <!-- Name used to refer to the "Up" arrow key on the keyboard. -->
+    <string name="keyboard_key_dpad_up">Up</string>
+    <!-- Name used to refer to the "Down" arrow key on the keyboard. -->
+    <string name="keyboard_key_dpad_down">Down</string>
+    <!-- Name used to refer to the "Left" arrow key on the keyboard. -->
+    <string name="keyboard_key_dpad_left">Left</string>
+    <!-- Name used to refer to the "Right" arrow key on the keyboard. -->
+    <string name="keyboard_key_dpad_right">Right</string>
+    <!-- Name used to refer to the "Center" arrow key on the keyboard. -->
+    <string name="keyboard_key_dpad_center">Center</string>
+    <!-- Name used to refer to the "Tab" key on the keyboard. -->
+    <string name="keyboard_key_tab">Tab</string>
+    <!-- Name used to refer to the "Space" key on the keyboard. -->
+    <string name="keyboard_key_space">Space</string>
+    <!-- Name used to refer to the "Enter" key on the keyboard. -->
+    <string name="keyboard_key_enter">Enter</string>
+    <!-- Name used to refer to the "Backspace" key on the keyboard. -->
+    <string name="keyboard_key_backspace">Backspace</string>
+    <!-- Name used to refer to the "Play/Pause" media key on the keyboard. -->
+    <string name="keyboard_key_media_play_pause">Play/Pause</string>
+    <!-- Name used to refer to the "Stop" media key on the keyboard. -->
+    <string name="keyboard_key_media_stop">Stop</string>
+    <!-- Name used to refer to the "Next" media key on the keyboard. -->
+    <string name="keyboard_key_media_next">Next</string>
+    <!-- Name used to refer to the "Previous" media key on the keyboard. -->
+    <string name="keyboard_key_media_previous">Previous</string>
+    <!-- Name used to refer to the "Rewind" media key on the keyboard. -->
+    <string name="keyboard_key_media_rewind">Rewind</string>
+    <!-- Name used to refer to the "Fast Forward" media key on the keyboard. -->
+    <string name="keyboard_key_media_fast_forward">Fast Forward</string>
+    <!-- Name used to refer to the "Page Up" key on the keyboard. -->
+    <string name="keyboard_key_page_up">Page Up</string>
+    <!-- Name used to refer to the "Page Down" key on the keyboard. -->
+    <string name="keyboard_key_page_down">Page Down</string>
+    <!-- Name used to refer to the "Delete" key on the keyboard. -->
+    <string name="keyboard_key_forward_del">Delete</string>
+    <!-- Name used to refer to the "Home" move key on the keyboard. -->
+    <string name="keyboard_key_move_home">Home</string>
+    <!-- Name used to refer to the "End" move key on the keyboard. -->
+    <string name="keyboard_key_move_end">End</string>
+    <!-- Name used to refer to the "Insert" key on the keyboard. -->
+    <string name="keyboard_key_insert">Insert</string>
+    <!-- Name used to refer to the "Num Lock" key on the keyboard. -->
+    <string name="keyboard_key_num_lock">Num Lock</string>
+    <!-- Name used to refer to keys on the numeric pad of the keyboard, e.g. "Numpad 9". -->
+    <string name="keyboard_key_numpad_template">Numpad <xliff:g id="name">%1$s</xliff:g></string>
+
     <!-- User visible title for the system-wide keyboard shortcuts list. -->
     <string name="keyboard_shortcut_group_system">System</string>
     <!-- User visible title for the keyboard shortcut that takes the user to the home screen. -->
@@ -1479,4 +1530,34 @@
     <!-- Accessibility action for moving down the docked stack divider [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_divider_move_right">Move right</string>
 
+    <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity and that things might crash/not work properly [CHAR LIMIT=NONE] -->
+    <string name="forced_resizable_info_text">App may not work with multi-window</string>
+
+    <!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_tile_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>, <xliff:g id="tile_name" example="Wi-Fi">%2$s</xliff:g>. Double tap to edit.</string>
+
+    <!-- Accessibility description of a QS tile while editing positions [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_add_tile_label"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g>. Double tap to add.</string>
+
+    <!-- Accessibility description of a place to drop a tile while editing positions [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_position_label">Position <xliff:g id="position" example="2">%1$d</xliff:g>. Double tap to select.</string>
+
+    <!-- Accessibility description of option to move QS tile [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_move_tile">Move <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g></string>
+
+    <!-- Accessibility description of option to remove QS tile [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_remove_tile">Remove <xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g></string>
+
+    <!-- Accessibility action when QS tile is added [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_tile_added"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> is added to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
+
+    <!-- Accessibility action when QS tile is removed [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_tile_removed"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> is removed</string>
+
+    <!-- Accessibility action when QS tile is moved [CHAR LIMIT=NONE] -->
+    <string name="accessibility_qs_edit_tile_moved"><xliff:g id="tile_name" example="Wi-Fi">%1$s</xliff:g> moved to position <xliff:g id="position" example="5">%2$d</xliff:g></string>
+
+    <!-- Accessibility label for window when QS editing is happening [CHAR LIMIT=NONE] -->
+    <string name="accessibility_desc_quick_settings_edit">Quick settings editor.</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 21ad216..2b134af 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -40,6 +40,18 @@
         <item name="android:windowBackground">@android:color/black</item>
     </style>
 
+    <!-- Theme used for the activity that shows when the system forced an app to be resizable -->
+    <style name="ForcedResizableTheme" parent="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
+        <item name="android:windowBackground">@drawable/forced_resizable_background</item>
+        <item name="android:statusBarColor">@color/transparent</item>
+        <item name="android:windowAnimationStyle">@style/Animation.ForcedResizable</item>
+    </style>
+
+    <style name="Animation.ForcedResizable" parent="@android:style/Animation">
+        <item name="android:activityOpenEnterAnimation">@anim/forced_resizable_enter</item>
+        <item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
+    </style>
+
     <style name="TextAppearance.StatusBar.HeadsUp"
         parent="@*android:style/TextAppearance.StatusBar">
     </style>
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 9f2745b..28ed84f 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -30,8 +30,6 @@
 
     @Retention(RetentionPolicy.SOURCE)
     @StringDef({
-        Key.OVERVIEW_SEARCH_APP_WIDGET_ID,
-        Key.OVERVIEW_SEARCH_APP_WIDGET_PACKAGE,
         Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME,
         Key.DEBUG_MODE_ENABLED,
         Key.HOTSPOT_TILE_LAST_USED,
@@ -51,8 +49,6 @@
         Key.QS_NIGHT_ADDED,
     })
     public @interface Key {
-        String OVERVIEW_SEARCH_APP_WIDGET_ID = "searchAppWidgetId";
-        String OVERVIEW_SEARCH_APP_WIDGET_PACKAGE = "searchAppWidgetPackage";
         String OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME = "OverviewLastStackTaskActiveTime";
         String DEBUG_MODE_ENABLED = "debugModeEnabled";
         String HOTSPOT_TILE_LAST_USED = "HotspotTileLastUsed";
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index a08b2c1..8f79bda 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -274,10 +274,7 @@
                             mWatchLongPress = new Runnable() {
                                 @Override
                                 public void run() {
-                                    float pos = getPos(ev);
-                                    float delta = pos - mInitialTouchPos;
-                                    if (mCurrView != null && !mLongPressSent
-                                            && Math.abs(delta) < mPagingTouchSlop) {
+                                    if (mCurrView != null && !mLongPressSent) {
                                         mLongPressSent = true;
                                         mCurrView.sendAccessibilityEvent(
                                                 AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 2e94bc7..0d75fdd 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -25,6 +25,8 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowManager;
@@ -75,6 +77,11 @@
         return new ScrimController(scrimBehind, scrimInFront, headsUpScrim);
     }
 
+    public NotificationIconAreaController createNotificationIconAreaController(Context context,
+            PhoneStatusBar phoneStatusBar) {
+        return new NotificationIconAreaController(context, phoneStatusBar);
+    }
+
     public <T> T createInstance(Class<T> classType) {
         return null;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 522d533..109a456 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -183,14 +183,16 @@
                     return;
                 }
 
+                boolean isPowerSaver = mPowerManager.isPowerSaveMode();
                 if (!plugged
+                        && !isPowerSaver
                         && (bucket < oldBucket || oldPlugged)
                         && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
                         && bucket < 0) {
                     // only play SFX when the dialog comes up or the bucket changes
                     final boolean playSound = bucket != oldBucket || oldPlugged;
                     mWarnings.showLowBatteryWarning(playSound);
-                } else if (plugged || (bucket > oldBucket && bucket > 0)) {
+                } else if (isPowerSaver || plugged || (bucket > oldBucket && bucket > 0)) {
                     mWarnings.dismissLowBatteryWarning();
                 } else {
                     mWarnings.updateLowBatteryWarning();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
index 1200266..ba07bf4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
@@ -1,86 +1,219 @@
 package com.android.systemui.qs;
 
 import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
+import android.graphics.drawable.AnimatedVectorDrawable;
 import android.util.AttributeSet;
-import android.view.Gravity;
+import android.util.Log;
 import android.view.View;
-import android.widget.LinearLayout;
-
+import android.view.ViewGroup;
+import android.widget.ImageView;
 import com.android.systemui.R;
 
-public class PageIndicator extends LinearLayout {
+import java.util.ArrayList;
 
-    private final int mPageIndicatorSize;
+public class PageIndicator extends ViewGroup {
+
+    private static final String TAG = "PageIndicator";
+    private static final boolean DEBUG = false;
+
+    private static final long ANIMATION_DURATION = 250;
+
+    // The size of a single dot in relation to the whole animation.
+    private static final float SINGLE_SCALE = .4f;
+
+    private static final float MINOR_ALPHA = .3f;
+
+    private final ArrayList<Integer> mQueuedPositions = new ArrayList<>();
+
+    private final int mPageIndicatorWidth;
+    private final int mPageIndicatorHeight;
+    private final int mPageDotWidth;
+
+    private int mPosition = -1;
+    private boolean mAnimating;
 
     public PageIndicator(Context context, AttributeSet attrs) {
         super(context, attrs);
-        setGravity(Gravity.CENTER);
-        mPageIndicatorSize =
-                (int) mContext.getResources().getDimension(R.dimen.qs_page_indicator_size);
+        mPageIndicatorWidth =
+                (int) mContext.getResources().getDimension(R.dimen.qs_page_indicator_width);
+        mPageIndicatorHeight =
+                (int) mContext.getResources().getDimension(R.dimen.qs_page_indicator_height);
+        mPageDotWidth = (int) (mPageIndicatorWidth * SINGLE_SCALE);
     }
 
     public void setNumPages(int numPages) {
+        setVisibility(numPages > 1 ? View.VISIBLE : View.INVISIBLE);
+        if (mAnimating) {
+            Log.w(TAG, "setNumPages during animation");
+        }
         while (numPages < getChildCount()) {
             removeViewAt(getChildCount() - 1);
         }
         while (numPages > getChildCount()) {
-            SinglePageIndicator v = new SinglePageIndicator(mContext);
-            v.setAmount(0);
-            addView(v, new LayoutParams(mPageIndicatorSize, mPageIndicatorSize));
+            ImageView v = new ImageView(mContext);
+            v.setImageResource(R.drawable.minor_a_b);
+            addView(v, new LayoutParams(mPageIndicatorWidth, mPageIndicatorHeight));
         }
+        // Refresh state.
+        setIndex(mPosition >> 1);
     }
 
     public void setLocation(float location) {
         int index = (int) location;
-        location -= index;
+        int position = index << 1 | ((location != index) ? 1 : 0);
+        if (DEBUG) Log.d(TAG, "setLocation " + location + " " + index + " " + position);
 
+        int lastPosition = mPosition;
+        if (mQueuedPositions.size() != 0) {
+            lastPosition = mQueuedPositions.get(mQueuedPositions.size() - 1);
+        }
+        if (position == lastPosition) return;
+        if (mAnimating) {
+            if (DEBUG) Log.d(TAG, "Queueing transition to " + Integer.toHexString(position));
+            mQueuedPositions.add(position);
+            return;
+        }
+
+        setPosition(position);
+    }
+
+    private void setPosition(int position) {
+        if (isVisibleToUser() && Math.abs(mPosition - position) == 1) {
+            animate(mPosition, position);
+        } else {
+            if (DEBUG) Log.d(TAG, "Skipping animation " + isVisibleToUser() + " " + mPosition
+                    + " " + position);
+            setIndex(position >> 1);
+        }
+        mPosition = position;
+    }
+
+    private void setIndex(int index) {
         final int N = getChildCount();
         for (int i = 0; i < N; i++) {
-            float amount = 0;
-            if (i == index) {
-                amount = 1 - location;
-            } else if (i == index + 1) {
-                amount = location;
+            ImageView v = (ImageView) getChildAt(i);
+            // Clear out any animation positioning.
+            v.setTranslationX(0);
+            v.setImageResource(R.drawable.major_a_b);
+            v.setAlpha(getAlpha(i == index));
+        }
+    }
+
+    private void animate(int from, int to) {
+        if (DEBUG) Log.d(TAG, "Animating from " + Integer.toHexString(from) + " to "
+                + Integer.toHexString(to));
+        int fromIndex = from >> 1;
+        int toIndex = to >> 1;
+
+        // Set the position of everything, then we will manually control the two views involved
+        // in the animation.
+        setIndex(fromIndex);
+
+        boolean fromTransition = (from & 1) != 0;
+        boolean isAState = fromTransition ? from > to : from < to;
+        int firstIndex = Math.min(fromIndex, toIndex);
+        int secondIndex = Math.max(fromIndex, toIndex);
+        if (secondIndex == firstIndex) {
+            secondIndex++;
+        }
+        ImageView first = (ImageView) getChildAt(firstIndex);
+        ImageView second = (ImageView) getChildAt(secondIndex);
+        // Lay the two views on top of each other.
+        second.setTranslationX(first.getX() - second.getX());
+
+        playAnimation(first, getTransition(fromTransition, isAState, false));
+        first.setAlpha(getAlpha(false));
+
+        playAnimation(second, getTransition(fromTransition, isAState, true));
+        second.setAlpha(getAlpha(true));
+
+        mAnimating = true;
+    }
+
+    private float getAlpha(boolean isMajor) {
+        return isMajor ? 1 : MINOR_ALPHA;
+    }
+
+    private void playAnimation(ImageView imageView, int res) {
+        final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) getContext().getDrawable(res);
+        imageView.setImageDrawable(avd);
+        avd.forceAnimationOnUI();
+        avd.start();
+        // TODO: Figure out how to user an AVD animation callback instead, which doesn't
+        // seem to be working right now...
+        postDelayed(mAnimationDone, ANIMATION_DURATION);
+    }
+
+    private int getTransition(boolean fromB, boolean isMajorAState, boolean isMajor) {
+        if (isMajor) {
+            if (fromB) {
+                if (isMajorAState) {
+                    return R.drawable.major_b_a_animation;
+                } else {
+                    return R.drawable.major_b_c_animation;
+                }
+            } else {
+                if (isMajorAState) {
+                    return R.drawable.major_a_b_animation;
+                } else {
+                    return R.drawable.major_c_b_animation;
+                }
             }
-            ((SinglePageIndicator) getChildAt(i)).setAmount(amount);
+        } else {
+            if (fromB) {
+                if (isMajorAState) {
+                    return R.drawable.minor_b_c_animation;
+                } else {
+                    return R.drawable.minor_b_a_animation;
+                }
+            } else {
+                if (isMajorAState) {
+                    return R.drawable.minor_c_b_animation;
+                } else {
+                    return R.drawable.minor_a_b_animation;
+                }
+            }
         }
     }
 
-    // This could be done with a circle drawable and an ImageView, but this seems
-    // easier for now.
-    public static class SinglePageIndicator extends View {
-        private static final int MIN_ALPHA = 0x4d;
-        private static final int MAX_ALPHA = 0xff;
-
-        private static final float MIN_SIZE = .55f;
-        private static final float MAX_SIZE = .7f;
-
-        private final Paint mPaint;
-        private float mSize;
-
-        public SinglePageIndicator(Context context) {
-            super(context);
-            mPaint = new Paint();
-            mPaint.setColor(0xffffffff);
-            mPaint.setAlpha(MAX_ALPHA);
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int N = getChildCount();
+        if (N == 0) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            return;
         }
-
-        public void setAmount(float amount) {
-            mSize = amount * (MAX_SIZE - MIN_SIZE) + MIN_SIZE;
-            int alpha = (int) (amount * (MAX_ALPHA - MIN_ALPHA)) + MIN_ALPHA;
-            mPaint.setAlpha(alpha);
-            postInvalidate();
+        final int widthChildSpec = MeasureSpec.makeMeasureSpec(mPageIndicatorWidth,
+                MeasureSpec.EXACTLY);
+        final int heightChildSpec = MeasureSpec.makeMeasureSpec(mPageIndicatorHeight,
+                MeasureSpec.EXACTLY);
+        for (int i = 0; i < N; i++) {
+            getChildAt(i).measure(widthChildSpec, heightChildSpec);
         }
+        int width = (mPageIndicatorWidth - mPageDotWidth) * N + mPageDotWidth;
+        setMeasuredDimension(width, mPageIndicatorHeight);
+    }
 
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int N = getChildCount();
+        if (N == 0) {
+            return;
+        }
+        for (int i = 0; i < N; i++) {
+            int left = (mPageIndicatorWidth - mPageDotWidth) * i;
+            getChildAt(i).layout(left, 0, mPageIndicatorWidth + left, mPageIndicatorHeight);
+        }
+    }
+
+    private final Runnable mAnimationDone = new Runnable() {
         @Override
-        public void draw(Canvas canvas) {
-            int minDimen = Math.min(getWidth(), getHeight()) / 2;
-            float radius = mSize * minDimen;
-            float x = getWidth() / 2f;
-            float y = getHeight() / 2f;
-            canvas.drawCircle(x, y, radius, mPaint);
+        public void run() {
+            if (DEBUG) Log.d(TAG, "onAnimationEnd - queued: " + mQueuedPositions.size());
+            mAnimating = false;
+            if (mQueuedPositions.size() != 0) {
+                setPosition(mQueuedPositions.remove(0));
+            }
         }
-    }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 24b45cc..fd43aa0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -36,7 +36,6 @@
             @Override
             public void onPageSelected(int position) {
                 if (mPageIndicator == null) return;
-                mPageIndicator.setLocation(position);
                 if (mPageListener != null) {
                     mPageListener.onPageChanged(position == 0);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index 5b05e84..43ebe04 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -140,6 +140,8 @@
     public void notifyCustomizeChanged() {
         // The customize state changed, so our height changed.
         updateBottom();
+        mQSPanel.setVisibility(!mQSCustomizer.isCustomizing() ? View.VISIBLE : View.INVISIBLE);
+        mHeader.setVisibility(!mQSCustomizer.isCustomizing() ? View.VISIBLE : View.INVISIBLE);
         // Let the panel know the position changed and it needs to update where notifications
         // and whatnot are.
         mPanelView.onQsHeightChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 6d8b476..51efbf0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -36,12 +36,12 @@
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.SecurityController;
 
+import static android.provider.Settings.ACTION_VPN_SETTINGS;
+
 public class QSFooter implements OnClickListener, DialogInterface.OnClickListener {
     protected static final String TAG = "QSFooter";
     protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final String ACTION_VPN_SETTINGS = "android.net.vpn.SETTINGS";
-
     private final View mRootView;
     private final TextView mFooterText;
     private final ImageView mFooterIcon;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 42e98aa..1659888 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -294,6 +294,8 @@
         }
     }
 
+    public abstract CharSequence getTileLabel();
+
     protected final class H extends Handler {
         private static final int ADD_CALLBACK = 1;
         private static final int CLICK = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 03c2a0b..353c6b6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -14,7 +14,10 @@
 
 package com.android.systemui.qs.customize;
 
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.graphics.Canvas;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Handler;
@@ -27,7 +30,10 @@
 import android.support.v7.widget.helper.ItemTouchHelper;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 import com.android.systemui.R;
@@ -37,6 +43,7 @@
 import com.android.systemui.qs.customize.TileQueryHelper.TileInfo;
 import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
 import com.android.systemui.statusbar.phone.QSTileHost;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -49,21 +56,27 @@
 
     private static final int TYPE_TILE = 0;
     private static final int TYPE_EDIT = 1;
+    private static final int TYPE_ACCESSIBLE_DROP = 2;
 
     private final Context mContext;
 
     private final Handler mHandler = new Handler();
     private final List<TileInfo> mTiles = new ArrayList<>();
     private final ItemTouchHelper mItemTouchHelper;
+    private final AccessibilityManager mAccessibilityManager;
     private int mDividerIndex;
+    private boolean mNeedsFocus;
     private List<String> mCurrentSpecs;
     private List<TileInfo> mOtherTiles;
     private List<TileInfo> mAllTiles;
 
     private Holder mCurrentDrag;
+    private boolean mAccessibilityMoving;
+    private int mAccessibilityFromIndex;
 
     public TileAdapter(Context context) {
         mContext = context;
+        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         mItemTouchHelper = new ItemTouchHelper(mCallbacks);
         setHasStableIds(true);
     }
@@ -130,6 +143,9 @@
 
     @Override
     public int getItemViewType(int position) {
+        if (mAccessibilityMoving && position == mDividerIndex - 1) {
+            return TYPE_ACCESSIBLE_DROP;
+        }
         if (mTiles.get(position) == null) {
             return TYPE_EDIT;
         }
@@ -140,7 +156,7 @@
     public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
         final Context context = parent.getContext();
         LayoutInflater inflater = LayoutInflater.from(context);
-        if (viewType == 1) {
+        if (viewType == TYPE_EDIT) {
             return new Holder(inflater.inflate(R.layout.qs_customize_divider, parent, false));
         }
         FrameLayout frame = (FrameLayout) inflater.inflate(R.layout.qs_customize_tile_frame, parent,
@@ -155,22 +171,157 @@
     }
 
     @Override
-    public void onBindViewHolder(final Holder holder, int position) {
+    public void onBindViewHolder(final Holder holder, final int position) {
         if (holder.getItemViewType() == TYPE_EDIT) {
             ((TextView) holder.itemView.findViewById(android.R.id.title)).setText(
                     mCurrentDrag != null ? R.string.drag_to_remove_tiles
                     : R.string.drag_to_add_tiles);
             return;
         }
+        if (holder.getItemViewType() == TYPE_ACCESSIBLE_DROP) {
+            holder.mTileView.setClickable(true);
+            holder.mTileView.setFocusable(true);
+            holder.mTileView.setFocusableInTouchMode(true);
+            holder.mTileView.setVisibility(View.VISIBLE);
+            holder.mTileView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+            holder.mTileView.setContentDescription(mContext.getString(
+                    R.string.accessibility_qs_edit_position_label, position + 1));
+            holder.mTileView.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    selectPosition(position, v);
+                }
+            });
+            if (mNeedsFocus) {
+                // Wait for this to get laid out then set its focus.
+                holder.mTileView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+                    @Override
+                    public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                            int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                        holder.mTileView.removeOnLayoutChangeListener(this);
+                        holder.mTileView.requestFocus();
+                    }
+                });
+                mNeedsFocus = false;
+            }
+            return;
+        }
 
         TileInfo info = mTiles.get(position);
+
+        if (position > mDividerIndex) {
+            info.state.contentDescription = mContext.getString(
+                    R.string.accessibility_qs_edit_add_tile_label, info.state.label);
+        } else if (mAccessibilityMoving) {
+            info.state.contentDescription = mContext.getString(
+                    R.string.accessibility_qs_edit_position_label, position + 1);
+        } else {
+            info.state.contentDescription = mContext.getString(
+                    R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label);
+        }
         holder.mTileView.onStateChanged(info.state);
+
+        if (mAccessibilityManager.isTouchExplorationEnabled()) {
+            final boolean selectable = !mAccessibilityMoving || position < mDividerIndex;
+            holder.mTileView.setClickable(selectable);
+            holder.mTileView.setFocusable(selectable);
+            holder.mTileView.setImportantForAccessibility(selectable
+                    ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
+                    : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+            if (selectable) {
+                holder.mTileView.setOnClickListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        if (mAccessibilityMoving) {
+                            selectPosition(position, v);
+                        } else {
+                            if (position < mDividerIndex) {
+                                showAccessibilityDialog(position, v);
+                            } else {
+                                startAccessibleDrag(position);
+                            }
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    private void selectPosition(int position, View v) {
+        // Remove the placeholder.
+        mTiles.remove(mDividerIndex--);
+        mAccessibilityMoving = false;
+        move(mAccessibilityFromIndex, position, v);
+        notifyDataSetChanged();
+    }
+
+    private void showAccessibilityDialog(final int position, final View v) {
+        TileInfo info = mTiles.get(position);
+        CharSequence[] options = new CharSequence[] {
+                mContext.getString(R.string.accessibility_qs_edit_move_tile, info.state.label),
+                mContext.getString(R.string.accessibility_qs_edit_remove_tile, info.state.label),
+        };
+        AlertDialog dialog = new Builder(mContext)
+                .setItems(options, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        if (which == 0) {
+                            startAccessibleDrag(position);
+                        } else {
+                            move(position, mDividerIndex, v);
+                        }
+                    }
+                }).setNegativeButton(android.R.string.cancel, null)
+                .create();
+        SystemUIDialog.setShowForAllUsers(dialog, true);
+        SystemUIDialog.applyFlags(dialog);
+        dialog.show();
+    }
+
+    private void startAccessibleDrag(int position) {
+        mAccessibilityMoving = true;
+        mNeedsFocus = true;
+        mAccessibilityFromIndex = position;
+        // Add placeholder for last slot.
+        mTiles.add(mDividerIndex++, null);
+        notifyDataSetChanged();
     }
 
     public SpanSizeLookup getSizeLookup() {
         return mSizeLookup;
     }
 
+    private boolean move(int from, int to, View v) {
+        if (to > mDividerIndex) {
+            if (from >= mDividerIndex) {
+                return false;
+            }
+        }
+        CharSequence fromLabel = mTiles.get(from).state.label;
+        move(from, to, mTiles);
+        mDividerIndex = mTiles.indexOf(null);
+        notifyItemChanged(from);
+        notifyItemMoved(from, to);
+        CharSequence announcement;
+        if (to >= mDividerIndex) {
+            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_removed,
+                    fromLabel);
+        } else if (from >= mDividerIndex) {
+            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_added,
+                    fromLabel, (to + 1));
+        } else {
+            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_moved,
+                    fromLabel, (to + 1));
+        }
+        v.announceForAccessibility(announcement);
+        return true;
+    }
+
+    private <T> void move(int from, int to, List<T> list) {
+        list.add(from > to ? to : to + 1, list.get(from));
+        list.remove(from > to ? from + 1 : from);
+    }
+
     public class Holder extends ViewHolder {
         private QSTileView mTileView;
 
@@ -286,20 +437,7 @@
         public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) {
             int from = viewHolder.getAdapterPosition();
             int to = target.getAdapterPosition();
-            if (to > mDividerIndex) {
-                if (from >= mDividerIndex) {
-                    return false;
-                }
-            }
-            move(from, to, mTiles);
-            mDividerIndex = mTiles.indexOf(null);
-            notifyItemMoved(from, to);
-            return true;
-        }
-
-        private <T> void move(int from, int to, List<T> list) {
-            list.add(from > to ? to : to + 1, list.get(from));
-            list.remove(from > to ? from + 1 : from);
+            return move(from, to, target.itemView);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index d95d3ef..bbc8856 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -33,7 +33,6 @@
 import com.android.systemui.qs.QSTile.DrawableIcon;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.statusbar.phone.QSTileHost;
-import com.android.systemui.tuner.TunerService;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -75,6 +74,8 @@
                 public void run() {
                     final QSTile.State state = tile.newTileState();
                     tile.getState().copyTo(state);
+                    // Ignore the current state and get the generic label instead.
+                    state.label = tile.getTileLabel();
                     mainHandler.post(new Runnable() {
                         @Override
                         public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 9156f3a..6114573 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -221,6 +221,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return getState().label;
+    }
+
+    @Override
     protected void handleUpdateState(State state, Object arg) {
         Drawable drawable = mTile.getIcon().loadDrawable(mContext);
         int tileState = mTile.getState();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 89f1985b..5f5a87e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -76,6 +76,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.airplane_mode);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();
         final boolean airplaneMode = value != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 2e87525..6ddd46e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -106,6 +106,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.battery);
+    }
+
+    @Override
     protected void handleUpdateState(State state, Object arg) {
         int level = (arg != null) ? (Integer) arg : mLevel;
         String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 80f667c..1fef8f1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -96,6 +96,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_bluetooth_label);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         final boolean enabled = mController.isBluetoothEnabled();
         final boolean connected = mController.isBluetoothConnected();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index e0ad002..bea1e15 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -108,6 +108,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_cast_title);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.label = mContext.getString(R.string.quick_settings_cast_title);
         state.value = false;
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 5f87741..55b00b5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -101,6 +101,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_cellular_detail_title);
+    }
+
+    @Override
     protected void handleUpdateState(SignalState state, Object arg) {
         CallbackInfo cb = (CallbackInfo) arg;
         if (cb == null) {
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 a608316..416132e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -85,6 +85,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_inversion_label);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
         final boolean enabled = value != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index 74b3fdc..35aff21 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -57,6 +57,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.data_saver);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.value = arg instanceof Boolean ? (Boolean) arg
                 : mDataSaverController.isDataSaverEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 8b22868..11efd56 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -128,6 +128,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_dnd_label);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
         final boolean newValue = zen != Global.ZEN_MODE_OFF;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index a01a9a5..69e71bc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -87,6 +87,16 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_flashlight_label);
+    }
+
+    @Override
+    protected void handleLongClick() {
+        handleClick();
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         if (!mFlashlightController.isAvailable()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index da93120..bf5b22c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -74,6 +74,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_hotspot_label);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index bb5ff8e..2a2cc46 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -119,6 +119,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return getState().label;
+    }
+
+    @Override
     protected void handleUpdateState(State state, Object arg) {
         Intent intent = (Intent) arg;
         if (intent == null) {
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 b1d1c77..6286f5e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -89,6 +89,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_location_label);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         final boolean locationEnabled =  mController.isLocationEnabled();
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index d80ca10..38b3706 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -80,6 +80,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return getState().label;
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         if (mController == null) return;
         final boolean rotationLocked = arg != null ? (Boolean) arg
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index f1066c1..5b4279c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -73,6 +73,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return getState().label;
+    }
+
+    @Override
     protected void handleUpdateState(State state, Object arg) {
         final Pair<String, Drawable> p = arg != null ? (Pair<String, Drawable>) arg : mLastUpdate;
         if (p != null) {
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 7ee795f..65154f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -119,6 +119,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_wifi_label);
+    }
+
+    @Override
     protected void handleUpdateState(SignalState state, Object arg) {
         if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
         CallbackInfo cb = (CallbackInfo) arg;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 421a2cf..2c5f7d5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -82,6 +82,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_work_mode_label);
+    }
+
+    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         if (arg instanceof Boolean) {
             state.value = (Boolean) arg;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 070b395..003379f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -27,6 +27,7 @@
         public static final int DismissSourceKeyboard = 0;
         public static final int DismissSourceSwipeGesture = 1;
         public static final int DismissSourceHeaderButton = 2;
+        @Deprecated
         public static final int DismissSourceHistorySwipeGesture = 3;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index da07aec..287bb22 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -180,7 +180,7 @@
     @Override
     public void start() {
         sDebugFlags = new RecentsDebugFlags(mContext);
-        sSystemServicesProxy = new SystemServicesProxy(mContext);
+        sSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
         sTaskLoader = new RecentsTaskLoader(mContext);
         sConfiguration = new RecentsConfiguration(mContext);
         mHandler = new Handler();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index aab45b5d..fe7ac71 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -18,10 +18,7 @@
 
 import android.app.Activity;
 import android.app.ActivityOptions;
-import android.app.SearchManager;
 import android.app.TaskStackBuilder;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -37,25 +34,24 @@
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.AppWidgetProviderChangedEvent;
 import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
 import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
 import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
-import com.android.systemui.recents.events.activity.HideHistoryEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
-import com.android.systemui.recents.events.activity.ShowHistoryEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
 import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
@@ -77,6 +73,7 @@
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.AnimationProps;
 import com.android.systemui.recents.views.RecentsView;
 import com.android.systemui.recents.views.SystemBarScrimViews;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -89,9 +86,6 @@
     private final static String TAG = "RecentsActivity";
     private final static boolean DEBUG = false;
 
-    private final static String KEY_SAVED_STATE_HISTORY_VISIBLE =
-            "saved_instance_state_history_visible";
-
     public final static int EVENT_BUS_PRIORITY = Recents.EVENT_BUS_PRIORITY + 1;
 
     private RecentsPackageMonitor mPackageMonitor;
@@ -104,11 +98,6 @@
     private RecentsView mRecentsView;
     private SystemBarScrimViews mScrimViews;
 
-    // Search AppWidget
-    private AppWidgetProviderInfo mSearchWidgetInfo;
-    private RecentsAppWidgetHost mAppWidgetHost;
-    private RecentsAppWidgetHostView mSearchWidgetHostView;
-
     // Runnables to finish the Recents activity
     private Intent mHomeIntent;
 
@@ -138,17 +127,10 @@
         @Override
         public void run() {
             try {
-                RecentsActivityLaunchState launchState =
-                        Recents.getConfiguration().getLaunchState();
                 ActivityOptions opts = mOpts;
                 if (opts == null) {
                     opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this,
-                            launchState.launchedFromSearchHome ?
-                                    R.anim.recents_to_search_launcher_enter :
-                                    R.anim.recents_to_launcher_enter,
-                            launchState.launchedFromSearchHome ?
-                                    R.anim.recents_to_search_launcher_exit :
-                                    R.anim.recents_to_launcher_exit);
+                            R.anim.recents_to_launcher_enter, R.anim.recents_to_launcher_exit);
                 }
                 startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
             } catch (Exception e) {
@@ -167,27 +149,11 @@
             if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                 // When the screen turns off, dismiss Recents to Home
                 dismissRecentsToHomeIfVisible(false);
-            } else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) {
-                // When the search activity changes, update the search widget view
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                mSearchWidgetInfo = ssp.getOrBindSearchAppWidget(context, mAppWidgetHost);
-                refreshSearchWidgetView();
             }
         }
     };
 
     /**
-     * Dismisses the history view back into the stack view.
-     */
-    boolean dismissHistory() {
-        if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
-            EventBus.getDefault().send(new HideHistoryEvent(true /* animate */));
-            return true;
-        }
-        return false;
-    }
-
-    /**
      * Dismisses recents if we are already visible and the intent is to toggle the recents view.
      */
     boolean dismissRecentsToFocusedTask(int logCategory) {
@@ -285,10 +251,7 @@
         // Register this activity with the event bus
         EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
 
-        // Initialize the widget host (the host id is static and does not change)
-        if (RecentsDebugFlags.Static.EnableSearchBar) {
-            mAppWidgetHost = new RecentsAppWidgetHost(this, RecentsAppWidgetHost.HOST_ID);
-        }
+        // Initialize the package monitor
         mPackageMonitor = new RecentsPackageMonitor();
         mPackageMonitor.register(this);
 
@@ -317,18 +280,15 @@
         mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
 
-        // Bind the search app widget when we first start up
-        if (RecentsDebugFlags.Static.EnableSearchBar) {
-            mSearchWidgetInfo = ssp.getOrBindSearchAppWidget(this, mAppWidgetHost);
-        }
-
         // Register the broadcast receiver to handle messages when the screen is turned off
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
-        if (RecentsDebugFlags.Static.EnableSearchBar) {
-            filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
-        }
         registerReceiver(mSystemBroadcastReceiver, filter);
+
+        getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION);
+
+        // Reload the stack view
+        reloadStackView();
     }
 
     @Override
@@ -341,15 +301,17 @@
     }
 
     @Override
-    public void onEnterAnimationComplete() {
-        super.onEnterAnimationComplete();
-        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+
+        // Reload the stack view
+        reloadStackView();
     }
 
-    @Override
-    protected void onResume() {
-        super.onResume();
-
+    /**
+     * Reloads the stack views upon launching Recents.
+     */
+    private void reloadStackView() {
         // If the Recents component has preloaded a load plan, then use that to prevent
         // reconstructing the task stack
         RecentsTaskLoader loader = Recents.getTaskLoader();
@@ -372,38 +334,21 @@
         loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
         loader.loadTasks(this, loadPlan, loadOpts);
         TaskStack stack = loadPlan.getTaskStack();
-        mRecentsView.onResume(mIsVisible, stack);
+        mRecentsView.onReload(mIsVisible, stack.getTaskCount() == 0);
+        mRecentsView.updateStack(stack);
 
-        // Animate the SystemUI scrims into view
-        Task launchTarget = stack.getLaunchTarget();
-        int taskCount = stack.getTaskCount();
-        int launchTaskIndexInStack = launchTarget != null
-                ? stack.indexOfStackTask(launchTarget)
-                : 0;
-        boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
+        // Update the nav bar scrim, but defer the animation until the enter-window event
         boolean animateNavBarScrim = !launchState.launchedWhileDocking;
-        mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
+        updateNavBarScrim(animateNavBarScrim, null);
 
-        // If this is a new instance from a configuration change, then we have to manually trigger
-        // the enter animation state, or if recents was relaunched by AM, without going through
-        // the normal mechanisms
+        // If this is a new instance relaunched by AM, without going through the normal mechanisms,
+        // then we have to manually trigger the enter animation state
         boolean wasLaunchedByAm = !launchState.launchedFromHome &&
                 !launchState.launchedFromApp;
-        if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
+        if (wasLaunchedByAm) {
             EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
         }
 
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-
-                    @Override
-                    public boolean onPreDraw() {
-                        mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
-                        EventBus.getDefault().post(new RecentsDrawnEvent());
-                        return true;
-                    }
-                });
-
         // Keep track of whether we launched from the nav bar button or via alt-tab
         if (launchState.launchedWithAltTab) {
             MetricsLogger.count(this, "overview_trigger_alttab", 1);
@@ -413,6 +358,10 @@
 
         // Keep track of whether we launched from an app or from home
         if (launchState.launchedFromApp) {
+            Task launchTarget = stack.getLaunchTarget();
+            int launchTaskIndexInStack = launchTarget != null
+                    ? stack.indexOfStackTask(launchTarget)
+                    : 0;
             MetricsLogger.count(this, "overview_source_app", 1);
             // If from an app, track the stack index of the app in the stack (for affiliated tasks)
             MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack);
@@ -421,6 +370,7 @@
         }
 
         // Keep track of the total stack task count
+        int taskCount = mRecentsView.getStack().getTaskCount();
         MetricsLogger.histogram(this, "overview_task_count", taskCount);
 
         // After we have resumed, set the visible state until the next onStop() call
@@ -428,6 +378,29 @@
     }
 
     @Override
+    public void onEnterAnimationComplete() {
+        super.onEnterAnimationComplete();
+        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // Notify of the next draw
+        mRecentsView.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+
+                    @Override
+                    public boolean onPreDraw() {
+                        mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
+                        EventBus.getDefault().post(new RecentsDrawnEvent());
+                        return true;
+                    }
+                });
+    }
+
+    @Override
     protected void onPause() {
         super.onPause();
 
@@ -439,18 +412,40 @@
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
-        EventBus.getDefault().send(new ConfigurationChangedEvent());
+        // Update the nav bar for the current orientation
+        updateNavBarScrim(false /* animateNavBarScrim */, AnimationProps.IMMEDIATE);
+
+        EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */));
+    }
+
+    @Override
+    public void onMultiWindowChanged(boolean inMultiWindow) {
+        super.onMultiWindowChanged(inMultiWindow);
+        EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */));
+
+        if (mRecentsView != null) {
+            // Reload the task stack completely
+            RecentsConfiguration config = Recents.getConfiguration();
+            RecentsActivityLaunchState launchState = config.getLaunchState();
+            RecentsTaskLoader loader = Recents.getTaskLoader();
+            RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
+            loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
+
+            RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
+            loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
+            loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
+            loader.loadTasks(this, loadPlan, loadOpts);
+
+            mRecentsView.updateStack(loadPlan.getTaskStack());
+        }
+
+        EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
     }
 
     @Override
     protected void onStop() {
         super.onStop();
 
-        // Only hide the history if Recents is completely hidden
-        if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
-            EventBus.getDefault().send(new HideHistoryEvent(false /* animate */));
-        }
-
         // Notify that recents is now hidden
         mIsVisible = false;
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
@@ -479,11 +474,6 @@
         // Unregister any broadcast receivers for the task loader
         mPackageMonitor.unregister();
 
-        // Stop listening for widget package changes if there was one bound
-        if (RecentsDebugFlags.Static.EnableSearchBar) {
-            mAppWidgetHost.stopListening();
-        }
-
         EventBus.getDefault().unregister(this);
     }
 
@@ -500,23 +490,6 @@
     }
 
     @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        if (RecentsDebugFlags.Static.EnableHistory) {
-            outState.putBoolean(KEY_SAVED_STATE_HISTORY_VISIBLE, mRecentsView.isHistoryVisible());
-        }
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle savedInstanceState) {
-        super.onRestoreInstanceState(savedInstanceState);
-        if (RecentsDebugFlags.Static.EnableHistory &&
-                savedInstanceState.getBoolean(KEY_SAVED_STATE_HISTORY_VISIBLE, false)) {
-            EventBus.getDefault().send(new ShowHistoryEvent());
-        }
-    }
-
-    @Override
     public void onTrimMemory(int level) {
         RecentsTaskLoader loader = Recents.getTaskLoader();
         if (loader != null) {
@@ -525,28 +498,6 @@
     }
 
     @Override
-    public void onMultiWindowChanged(boolean inMultiWindow) {
-        super.onMultiWindowChanged(inMultiWindow);
-        EventBus.getDefault().send(new ConfigurationChangedEvent());
-
-        // Reload the task stack completely
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
-        loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
-
-        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
-        loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
-        loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
-        loader.loadTasks(this, loadPlan, loadOpts);
-
-        mRecentsView.onResume(mIsVisible, loadPlan.getTaskStack());
-
-        EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
-    }
-
-    @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_TAB: {
@@ -611,39 +562,35 @@
     /**** EventBus events ****/
 
     public final void onBusEvent(ToggleRecentsEvent event) {
-        if (!RecentsDebugFlags.Static.EnableHistory || !dismissHistory()) {
-            RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-            if (launchState.launchedFromHome) {
-                dismissRecentsToHome(true /* animateTaskViews */);
-            } else {
-                dismissRecentsToLaunchTargetTaskOrHome();
-            }
+        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
+        if (launchState.launchedFromHome) {
+            dismissRecentsToHome(true /* animateTaskViews */);
+        } else {
+            dismissRecentsToLaunchTargetTaskOrHome();
         }
     }
 
     public final void onBusEvent(IterateRecentsEvent event) {
-        if (!RecentsDebugFlags.Static.EnableHistory || !dismissHistory()) {
-            final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
+        final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
 
-            // Start dozing after the recents button is clicked
-            int timerIndicatorDuration = 0;
-            if (debugFlags.isFastToggleRecentsEnabled()) {
-                timerIndicatorDuration = getResources().getInteger(
-                        R.integer.recents_subsequent_auto_advance_duration);
+        // Start dozing after the recents button is clicked
+        int timerIndicatorDuration = 0;
+        if (debugFlags.isFastToggleRecentsEnabled()) {
+            timerIndicatorDuration = getResources().getInteger(
+                    R.integer.recents_subsequent_auto_advance_duration);
 
-                mIterateTrigger.setDozeDuration(timerIndicatorDuration);
-                if (!mIterateTrigger.isDozing()) {
-                    mIterateTrigger.startDozing();
-                } else {
-                    mIterateTrigger.poke();
-                }
+            mIterateTrigger.setDozeDuration(timerIndicatorDuration);
+            if (!mIterateTrigger.isDozing()) {
+                mIterateTrigger.startDozing();
+            } else {
+                mIterateTrigger.poke();
             }
-
-            // Focus the next task
-            EventBus.getDefault().send(new FocusNextTaskViewEvent(timerIndicatorDuration));
-
-            MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
         }
+
+        // Focus the next task
+        EventBus.getDefault().send(new FocusNextTaskViewEvent(timerIndicatorDuration));
+
+        MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
     }
 
     public final void onBusEvent(UserInteractionEvent event) {
@@ -658,17 +605,7 @@
                 dismissRecentsToFocusedTaskOrHome();
             }
         } else if (event.triggeredFromHomeKey) {
-            // Otherwise, dismiss Recents to Home
-            if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
-                // If the history view is visible, then just cross-fade home
-                ActivityOptions opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this,
-                                R.anim.recents_to_launcher_enter,
-                                R.anim.recents_to_launcher_exit);
-                dismissRecentsToHome(false /* animate */, opts);
-
-            } else {
-                dismissRecentsToHome(true /* animateTaskViews */);
-            }
+            dismissRecentsToHome(true /* animateTaskViews */);
 
             // Cancel any pending dozes
             EventBus.getDefault().send(mUserInteractionEvent);
@@ -677,23 +614,6 @@
         }
     }
 
-    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
-        // Try and start the enter animation (or restart it on configuration changed)
-        if (RecentsDebugFlags.Static.EnableSearchBar) {
-            if (mSearchWidgetInfo != null) {
-                event.addPostAnimationCallback(new Runnable() {
-                    @Override
-                    public void run() {
-                        // Start listening for widget package changes if there is one bound
-                        if (mAppWidgetHost != null) {
-                            mAppWidgetHost.startListening();
-                        }
-                    }
-                });
-            }
-        }
-    }
-
     public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
         EventBus.getDefault().send(new UpdateFreeformTaskViewVisibilityEvent(true));
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
@@ -708,6 +628,11 @@
         mRecentsView.invalidate();
     }
 
+    public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
+        mRecentsView.getViewTreeObserver().addOnPreDrawListener(this);
+        mRecentsView.invalidate();
+    }
+
     public final void onBusEvent(CancelEnterRecentsWindowAnimationEvent event) {
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         int launchToTaskId = launchState.launchedToTaskId;
@@ -719,10 +644,6 @@
         }
     }
 
-    public final void onBusEvent(AppWidgetProviderChangedEvent event) {
-        refreshSearchWidgetView();
-    }
-
     public final void onBusEvent(ShowApplicationInfoEvent event) {
         // Create a new task stack with the application info details activity
         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
@@ -785,24 +706,6 @@
         mIgnoreAltTabRelease = true;
     }
 
-    private void refreshSearchWidgetView() {
-        if (mSearchWidgetInfo != null) {
-            SystemServicesProxy ssp = Recents.getSystemServices();
-            int searchWidgetId = ssp.getSearchAppWidgetId(this);
-            mSearchWidgetHostView = (RecentsAppWidgetHostView) mAppWidgetHost.createView(
-                    this, searchWidgetId, mSearchWidgetInfo);
-            Bundle opts = new Bundle();
-            opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
-                    AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
-            mSearchWidgetHostView.updateAppWidgetOptions(opts);
-            // Set the padding to 0 for this search widget
-            mSearchWidgetHostView.setPadding(0, 0, 0, 0);
-            mRecentsView.setSearchBar(mSearchWidgetHostView);
-        } else {
-            mRecentsView.setSearchBar(null);
-        }
-    }
-
     @Override
     public boolean onPreDraw() {
         mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
@@ -816,4 +719,18 @@
         });
         return true;
     }
+
+    /**
+     * Updates the nav bar scrim.
+     */
+    private void updateNavBarScrim(boolean animateNavBarScrim, AnimationProps animation) {
+        // Animate the SystemUI scrims into view
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        int taskCount = mRecentsView.getStack().getTaskCount();
+        boolean hasNavBarScrim = (taskCount > 0) && !ssp.hasTransposedNavBar();
+        mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
+        if (animateNavBarScrim && animation != null) {
+            mScrimViews.animateNavBarScrimVisibility(true, animation);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index ec4820a..77f7739 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -31,9 +31,6 @@
     public boolean launchedFromApp;
     public boolean launchedFromAppDocked;
     public boolean launchedFromHome;
-    public boolean launchedFromSearchHome;
-    public boolean launchedReuseTaskStackViews;
-    public boolean launchedHasConfigurationChanged;
     public boolean launchedViaDragGesture;
     public boolean launchedWhileDocking;
     public int launchedToTaskId;
@@ -42,12 +39,10 @@
 
     public void reset() {
         launchedFromHome = false;
-        launchedFromSearchHome = false;
         launchedFromApp = false;
         launchedFromAppDocked = false;
         launchedToTaskId = -1;
         launchedWithAltTab = false;
-        launchedHasConfigurationChanged = false;
         launchedViaDragGesture = false;
         launchedWhileDocking = false;
     }
@@ -55,10 +50,6 @@
     /** Called when the configuration has changed, and we want to reset any configuration specific
      * members. */
     public void updateOnConfigurationChange() {
-        // Reset this flag on configuration change to ensure that we recreate new task views
-        launchedReuseTaskStackViews = false;
-        // Set this flag to indicate that the configuration has changed since Recents last launched
-        launchedHasConfigurationChanged = true;
         launchedViaDragGesture = false;
         launchedWhileDocking = false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
deleted file mode 100644
index 318c69f..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java
+++ /dev/null
@@ -1,69 +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.recents;
-
-import android.appwidget.AppWidgetHost;
-import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.Context;
-
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.AppWidgetProviderChangedEvent;
-
-/** Our special app widget host for the Search widget */
-public class RecentsAppWidgetHost extends AppWidgetHost {
-
-    public static final int HOST_ID = 1024;
-
-    boolean mIsListening;
-
-    public RecentsAppWidgetHost(Context context, int hostId) {
-        super(context, hostId);
-    }
-
-    public void startListening() {
-        if (!mIsListening) {
-            mIsListening = true;
-            super.startListening();
-        }
-    }
-
-    @Override
-    public void stopListening() {
-        if (mIsListening) {
-            mIsListening = false;
-            super.stopListening();
-        }
-    }
-
-    @Override
-    protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
-                                             AppWidgetProviderInfo appWidget) {
-        return new RecentsAppWidgetHostView(context);
-    }
-
-    /**
-     * Note: this is only called for packages that have updated, not removed.
-     */
-    @Override
-    protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidgetInfo) {
-        super.onProviderChanged(appWidgetId, appWidgetInfo);
-        if (mIsListening) {
-            EventBus.getDefault().send(new AppWidgetProviderChangedEvent());
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHostView.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHostView.java
deleted file mode 100644
index 672d602..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHostView.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents;
-
-import android.appwidget.AppWidgetHostView;
-import android.content.Context;
-import android.view.View;
-import android.widget.RemoteViews;
-
-public class RecentsAppWidgetHostView extends AppWidgetHostView {
-
-    private Context mContext;
-    private int mPreviousOrientation;
-
-    public RecentsAppWidgetHostView(Context context) {
-        super(context);
-        mContext = context;
-    }
-
-    @Override
-    public void updateAppWidget(RemoteViews remoteViews) {
-        // Store the orientation in which the widget was inflated
-        updateLastInflationOrientation();
-        super.updateAppWidget(remoteViews);
-    }
-
-    @Override
-    protected View getErrorView() {
-        // Just return an empty view as the error view when failing to inflate the Recents search
-        // bar widget (this is mainly to catch the case where we try and inflate the widget view
-        // while the search provider is updating)
-        return new View(mContext);
-    }
-
-    /**
-     * Updates the last orientation that this widget was inflated.
-     */
-    private void updateLastInflationOrientation() {
-        mPreviousOrientation = mContext.getResources().getConfiguration().orientation;
-    }
-
-    /**
-     * @return whether the search widget was updated while Recents was in a different orientation
-     *         in the background.
-     */
-    public boolean isReinflateRequired() {
-        // Re-inflate is required if the orientation has changed since last inflated.
-        int orientation = mContext.getResources().getConfiguration().orientation;
-        if (mPreviousOrientation != orientation) {
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index eec0411..40613f0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -32,13 +32,6 @@
     private static final int LARGE_SCREEN_MIN_DP = 600;
     private static final int XLARGE_SCREEN_MIN_DP = 720;
 
-    // Variables that are used for global calculations
-    private static final float STACK_SIDE_PADDING_PHONES_PCT = 0.03333f;
-    private static final float STACK_SIZE_PADDING_TABLETS_PCT = 0.075f;
-    private static final float STACK_SIZE_PADDING_LARGE_TABLETS_PCT = 0.15f;
-    private static final int SEARCH_BAR_SPACE_HEIGHT_PHONES_DPS = 64;
-    private static final int SEARCH_BAR_SPACE_HEIGHT_TABLETS_DPS = 72;
-
     /** Levels of svelte in increasing severity/austerity. */
     // No svelting.
     public static final int SVELTE_NONE = 0;
@@ -54,13 +47,6 @@
     // Launch states
     public RecentsActivityLaunchState mLaunchState = new RecentsActivityLaunchState();
 
-    // TODO: Values determined by the current context, needs to be refactored into something that is
-    //       agnostic of the activity context, but still calculable from the Recents component for
-    //       the transition into recents
-    boolean hasTransposedSearchBar;
-    boolean hasTransposedNavBar;
-    public float taskStackWidthPaddingPct;
-
     // Since the positions in Recents has to be calculated globally (before the RecentsActivity
     // starts), we need to calculate some resource values ourselves, instead of relying on framework
     // resources.
@@ -71,7 +57,6 @@
     /** Misc **/
     public boolean fakeShadows;
     public int svelteLevel;
-    public int searchBarSpaceHeightPx;
 
     public RecentsConfiguration(Context context) {
         // Load only resources that can not change after the first load either through developer
@@ -82,28 +67,10 @@
         fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows);
         svelteLevel = res.getInteger(R.integer.recents_svelte_level);
 
-        float density = context.getResources().getDisplayMetrics().density;
+        float screenDensity = context.getResources().getDisplayMetrics().density;
         smallestWidth = ssp.getDeviceSmallestWidth();
-        isLargeScreen = smallestWidth >= (int) (density * LARGE_SCREEN_MIN_DP);
-        isXLargeScreen = smallestWidth >= (int) (density * XLARGE_SCREEN_MIN_DP);
-        searchBarSpaceHeightPx = isLargeScreen ?
-                (int) (density * SEARCH_BAR_SPACE_HEIGHT_TABLETS_DPS) :
-                (int) (density * SEARCH_BAR_SPACE_HEIGHT_PHONES_DPS);
-        if (isLargeScreen) {
-            taskStackWidthPaddingPct = STACK_SIZE_PADDING_TABLETS_PCT;
-        } else if (isXLargeScreen) {
-            taskStackWidthPaddingPct = STACK_SIZE_PADDING_LARGE_TABLETS_PCT;
-        } else {
-            taskStackWidthPaddingPct = STACK_SIDE_PADDING_PHONES_PCT;
-        }
-    }
-
-    /**
-     * Updates the configuration based on the current state of the system
-     */
-    void update(Rect systemInsets) {
-        hasTransposedNavBar = systemInsets.right > 0;
-        hasTransposedSearchBar = systemInsets.right > 0;
+        isLargeScreen = smallestWidth >= (int) (screenDensity * LARGE_SCREEN_MIN_DP);
+        isXLargeScreen = smallestWidth >= (int) (screenDensity * XLARGE_SCREEN_MIN_DP);
     }
 
     /**
@@ -121,40 +88,4 @@
     public void updateOnConfigurationChange() {
         mLaunchState.updateOnConfigurationChange();
     }
-
-    /**
-     * Returns the task stack bounds in the current orientation. These bounds do not account for
-     * the system insets.
-     */
-    public void getTaskStackBounds(Rect windowBounds, int topInset,
-            int rightInset, Rect searchBarBounds, Rect taskStackBounds) {
-        if (hasTransposedNavBar) {
-            // In landscape phones, the search bar appears on the left, but we overlay it on top
-            taskStackBounds.set(windowBounds.left, windowBounds.top + topInset,
-                    windowBounds.right - rightInset, windowBounds.bottom);
-        } else {
-            // In portrait, the search bar appears on the top (which already has the inset)
-            int top = searchBarBounds.isEmpty() ? topInset : 0;
-            taskStackBounds.set(windowBounds.left, windowBounds.top + searchBarBounds.bottom + top,
-                    windowBounds.right - rightInset, windowBounds.bottom);
-        }
-    }
-
-    /**
-     * Returns the search bar bounds in the current orientation.  These bounds do not account for
-     * the system insets.
-     */
-    public void getSearchBarBounds(Rect windowBounds, int topInset, Rect searchBarSpaceBounds) {
-        // Return empty rects if search is not enabled
-        int searchBarSize = searchBarSpaceHeightPx;
-        if (hasTransposedSearchBar) {
-            // In landscape phones, the search bar appears on the left
-            searchBarSpaceBounds.set(windowBounds.left, windowBounds.top + topInset,
-                    windowBounds.left + searchBarSize, windowBounds.bottom);
-        } else {
-            // In portrait, the search bar appears on the top
-            searchBarSpaceBounds.set(windowBounds.left, windowBounds.top + topInset,
-                    windowBounds.right, windowBounds.top + topInset + searchBarSize);
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index 40bf6d3..043510e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -31,14 +31,12 @@
     public static class Static {
         // Enables debug drawing for the transition thumbnail
         public static final boolean EnableTransitionThumbnailDebugMode = false;
-        // This enables the search bar integration
-        public static final boolean EnableSearchBar = false;
         // This disables the bitmap and icon caches
         public static final boolean DisableBackgroundCache = false;
         // Enables the task affiliations
-        public static final boolean EnableAffiliatedTaskGroups = true;
-        // Enables the history
-        public static final boolean EnableHistory = false;
+        public static final boolean EnableAffiliatedTaskGroups = false;
+        // TODO: To be repurposed
+        public static final boolean EnableStackActionButton = false;
         // Overrides the Tuner flags and enables the timeout
         private static final boolean EnableFastToggleTimeout = false;
         // Overrides the Tuner flags and enables the paging via the Recents button
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 880fe10..7daef64 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -20,8 +20,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
-import android.app.ITaskStackListener;
-import android.appwidget.AppWidgetProviderInfo;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
@@ -30,6 +28,7 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -41,12 +40,13 @@
 import android.view.ViewConfiguration;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.EventBus.Event;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
+import com.android.systemui.recents.events.activity.ForcedResizableEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
@@ -59,6 +59,7 @@
 import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.ForegroundThread;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 import com.android.systemui.recents.model.RecentsTaskLoadPlan;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
@@ -95,37 +96,13 @@
     public final static String RECENTS_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
 
     /**
-     * An implementation of ITaskStackListener, that allows us to listen for changes to the system
+     * An implementation of TaskStackListener, that allows us to listen for changes to the system
      * task stacks and update recents accordingly.
      */
-    class TaskStackListenerImpl extends ITaskStackListener.Stub implements Runnable {
-        Handler mHandler;
-
-        public TaskStackListenerImpl(Handler handler) {
-            mHandler = handler;
-        }
-
+    class TaskStackListenerImpl extends TaskStackListener {
         @Override
         public void onTaskStackChanged() {
-            // Debounce any task stack changes
-            mHandler.removeCallbacks(this);
-            mHandler.post(this);
-        }
-
-        @Override
-        public void onActivityPinned() {
-        }
-
-        @Override
-        public void onPinnedActivityRestartAttempt() {
-        }
-
-        @Override
-        public void onPinnedStackAnimationEnded() {
-        }
-
-        /** Preloads the next task */
-        public void run() {
+            // Preloads the next task
             RecentsConfiguration config = Recents.getConfiguration();
             if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
                 RecentsTaskLoader loader = Recents.getTaskLoader();
@@ -149,6 +126,13 @@
                 loader.loadTasks(mContext, plan, launchOpts);
             }
         }
+
+        @Override
+        public void onActivityForcedResizable(String packageName, int taskId) {
+            EventBus.getDefault().sendOntoMainThread(
+                    new ForcedResizableEvent(packageName, taskId));
+
+        }
     }
 
     protected static RecentsTaskLoadPlan sInstanceLoadPlan;
@@ -156,13 +140,10 @@
     protected Context mContext;
     protected Handler mHandler;
     TaskStackListenerImpl mTaskStackListener;
-    RecentsAppWidgetHost mAppWidgetHost;
-    protected boolean mCanReuseTaskStackViews = true;
     boolean mDraggingInRecents;
     boolean mLaunchedWhileDocking;
 
     // Task launching
-    Rect mSearchBarBounds = new Rect();
     Rect mTaskStackBounds = new Rect();
     Rect mLastTaskViewBounds = new Rect();
     TaskViewTransform mTmpTransform = new TaskViewTransform();
@@ -195,19 +176,18 @@
     public RecentsImpl(Context context) {
         mContext = context;
         mHandler = new Handler();
-        mAppWidgetHost = new RecentsAppWidgetHost(mContext, RecentsAppWidgetHost.HOST_ID);
 
         // Initialize the static foreground thread
         ForegroundThread.get();
 
         // Register the task stack listener
-        mTaskStackListener = new TaskStackListenerImpl(mHandler);
+        mTaskStackListener = new TaskStackListenerImpl();
         SystemServicesProxy ssp = Recents.getSystemServices();
         ssp.registerTaskStackListener(mTaskStackListener);
 
         // Initialize the static configuration resources
         reloadHeaderBarLayout();
-        updateHeaderBarLayout(true /* tryAndBindSearchWidget */, null /* stack */);
+        updateHeaderBarLayout(null /* stack */);
 
         // When we start, preload the data associated with the previous recent tasks.
         // We can use a new plan since the caches will be the same.
@@ -222,14 +202,12 @@
     }
 
     public void onBootCompleted() {
-        updateHeaderBarLayout(true /* tryAndBindSearchWidget */, null /* stack */);
+        updateHeaderBarLayout(null /* stack */);
     }
 
     public void onConfigurationChanged() {
         reloadHeaderBarLayout();
-        updateHeaderBarLayout(true /* tryAndBindSearchWidget */, null /* stack */);
-        // Don't reuse task stack views if the configuration changes
-        mCanReuseTaskStackViews = false;
+        updateHeaderBarLayout(null /* stack */);
         Recents.getConfiguration().updateOnConfigurationChange();
     }
 
@@ -585,8 +563,13 @@
                 com.android.internal.R.dimen.navigation_bar_height);
         mNavBarWidth = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.navigation_bar_width);
-        mTaskBarHeight = res.getDimensionPixelSize(
-                R.dimen.recents_task_bar_height);
+        mTaskBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height_tablet_land,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height_tablet_land);
         mDummyStackView = new TaskStackView(mContext);
         mHeaderBar = (TaskViewHeader) inflater.inflate(R.layout.recents_task_view_header,
                 null, false);
@@ -596,12 +579,9 @@
      * Prepares the header bar layout for the next transition, if the task view bounds has changed
      * since the last call, it will attempt to re-measure and layout the header bar to the new size.
      *
-     * @param tryAndBindSearchWidget if set, will attempt to fetch and bind the search widget if one
-     *                               is not already bound (can be expensive)
      * @param stack the stack to initialize the stack layout with
      */
-    private void updateHeaderBarLayout(boolean tryAndBindSearchWidget, TaskStack stack) {
-        RecentsConfiguration config = Recents.getConfiguration();
+    private void updateHeaderBarLayout(TaskStack stack) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         Rect systemInsets = new Rect();
         ssp.getStableInsets(systemInsets);
@@ -609,29 +589,17 @@
         calculateWindowStableInsets(systemInsets, windowRect);
         windowRect.offsetTo(0, 0);
 
-        // Update the configuration for the current state
-        config.update(systemInsets);
-
-        if (RecentsDebugFlags.Static.EnableSearchBar && tryAndBindSearchWidget) {
-            // Try and pre-emptively bind the search widget on startup to ensure that we
-            // have the right thumbnail bounds to animate to.
-            // Note: We have to reload the widget id before we get the task stack bounds below
-            if (ssp.getOrBindSearchAppWidget(mContext, mAppWidgetHost) != null) {
-                config.getSearchBarBounds(windowRect, mStatusBarHeight, mSearchBarBounds);
-            }
-        }
-        config.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right,
-                mSearchBarBounds, mTaskStackBounds);
+        TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
+        stackLayout.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right,
+                mTaskStackBounds);
 
         // Rebind the header bar and draw it for the transition
-        TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
         Rect taskStackBounds = new Rect(mTaskStackBounds);
         stackLayout.setSystemInsets(systemInsets);
         if (stack != null) {
-            stackLayout.initialize(taskStackBounds,
+            stackLayout.initialize(windowRect, taskStackBounds,
                     TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
-            mDummyStackView.setTasks(stack, false /* notifyStackChanges */,
-                    false /* relayoutTaskStack */);
+            mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
         }
         Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
         if (!taskViewBounds.equals(mLastTaskViewBounds)) {
@@ -688,7 +656,7 @@
         preloadIcon(topTask);
 
         // Update the header bar if necessary
-        updateHeaderBarLayout(false /* tryAndBindSearchWidget */, stack);
+        updateHeaderBarLayout(stack);
 
         // Update the destination rect
         final Task toTask = new Task();
@@ -721,13 +689,7 @@
     /**
      * Creates the activity options for a home->recents transition.
      */
-    protected ActivityOptions getHomeTransitionActivityOptions(boolean fromSearchHome) {
-        if (fromSearchHome) {
-            return ActivityOptions.makeCustomAnimation(mContext,
-                    R.anim.recents_from_search_launcher_enter,
-                    R.anim.recents_from_search_launcher_exit,
-                    mHandler, null);
-        }
+    protected ActivityOptions getHomeTransitionActivityOptions() {
         return ActivityOptions.makeCustomAnimation(mContext,
                 R.anim.recents_from_launcher_enter,
                 R.anim.recents_from_launcher_exit,
@@ -746,7 +708,7 @@
             TaskStackViewScroller stackScroller = stackView.getScroller();
 
             stackView.updateLayoutAlgorithm(true /* boundScroll */);
-            stackView.updateToInitialState();
+            stackView.updateToInitialState(true /* scrollToInitialState */);
 
             for (int i = tasks.size() - 1; i >= 0; i--) {
                 Task task = tasks.get(i);
@@ -813,7 +775,7 @@
 
         // Get the transform for the running task
         stackView.updateLayoutAlgorithm(true /* boundScroll */);
-        stackView.updateToInitialState();
+        stackView.updateToInitialState(true /* scrollToInitialState */);
         mTmpTransform = stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
                 stackView.getScroller().getStackScroll(), mTmpTransform, null);
         return mTmpTransform;
@@ -839,6 +801,12 @@
                 } else {
                     Canvas c = new Canvas(thumbnail);
                     c.scale(toTransform.scale, toTransform.scale);
+                    // Workaround for b/27815919, reset the callback so that we do not trigger an
+                    // invalidate on the header bar as a result of updating the icon
+                    Drawable icon = mHeaderBar.getIconView().getDrawable();
+                    if (icon != null) {
+                        icon.setCallback(null);
+                    }
                     mHeaderBar.rebindToTask(toTask, false /* touchExplorationEnabled */,
                             disabledInSafeMode);
                     mHeaderBar.setDimAlpha(toTransform.dimAlpha);
@@ -857,6 +825,7 @@
     protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
             boolean isTopTaskHome, boolean animate) {
         RecentsTaskLoader loader = Recents.getTaskLoader();
+        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
 
         // In the case where alt-tab is triggered, we never get a preloadRecents() call, so we
         // should always preload the tasks now. If we are dragging in recents, reload them as
@@ -868,31 +837,41 @@
         if (mLaunchedWhileDocking || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
             loader.preloadTasks(sInstanceLoadPlan, topTask.id, isTopTaskHome);
         }
+
         TaskStack stack = sInstanceLoadPlan.getTaskStack();
+        boolean hasRecentTasks = stack.getTaskCount() > 0;
+        boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks;
 
         // Update the header bar if necessary
-        updateHeaderBarLayout(false /* tryAndBindSearchWidget */, stack);
+        updateHeaderBarLayout(stack);
 
         // Prepare the dummy stack for the transition
         TaskStackLayoutAlgorithm.VisibilityReport stackVr =
                 mDummyStackView.computeStackVisibilityReport();
 
+        // Update the launch state
+        launchState.launchedFromHome = false;
+        launchState.launchedFromApp = mLaunchedWhileDocking;
+        launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
+        launchState.launchedFromAppDocked = mLaunchedWhileDocking;
+        launchState.launchedWithAltTab = mTriggeredFromAltTab;
+        launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks;
+        launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails;
+        launchState.launchedViaDragGesture = mDraggingInRecents;
+        launchState.launchedWhileDocking = mLaunchedWhileDocking;
+
         if (!animate) {
-            ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, -1, -1);
-            startRecentsActivity(topTask, opts, false /* fromHome */,
-                    false /* fromSearchHome */, false /* fromThumbnail*/, stackVr);
+            startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext, -1, -1));
             return;
         }
 
-        boolean hasRecentTasks = stack.getTaskCount() > 0;
-        boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks;
-
         if (useThumbnailTransition) {
+            launchState.launchedFromApp = true;
+
             // Try starting with a thumbnail transition
             ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView);
             if (opts != null) {
-                startRecentsActivity(topTask, opts, false /* fromHome */,
-                        false /* fromSearchHome */, true /* fromThumbnail */, stackVr);
+                startRecentsActivity(opts);
             } else {
                 // Fall through below to the non-thumbnail transition
                 useThumbnailTransition = false;
@@ -900,34 +879,14 @@
         }
 
         if (!useThumbnailTransition) {
-            // If there is no thumbnail transition, but is launching from home into recents, then
-            // use a quick home transition and do the animation from home
-            if (hasRecentTasks) {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                String homeActivityPackage = ssp.getHomeActivityPackageName();
-                String searchWidgetPackage = null;
-                if (RecentsDebugFlags.Static.EnableSearchBar) {
-                    searchWidgetPackage = Prefs.getString(mContext,
-                            Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_PACKAGE, null);
-                } else {
-                    AppWidgetProviderInfo searchWidgetInfo = ssp.resolveSearchAppWidget();
-                    if (searchWidgetInfo != null) {
-                        searchWidgetPackage = searchWidgetInfo.provider.getPackageName();
-                    }
-                }
+            launchState.launchedFromHome = true;
 
-                // Determine whether we are coming from a search owned home activity
-                boolean fromSearchHome = (homeActivityPackage != null) &&
-                        homeActivityPackage.equals(searchWidgetPackage);
-                ActivityOptions opts = getHomeTransitionActivityOptions(fromSearchHome);
-                startRecentsActivity(topTask, opts, true /* fromHome */, fromSearchHome,
-                        false /* fromThumbnail */, stackVr);
-            } else {
-                // Otherwise we do the normal fade from an unknown source
-                ActivityOptions opts = getUnknownTransitionActivityOptions();
-                startRecentsActivity(topTask, opts, true /* fromHome */,
-                        false /* fromSearchHome */, false /* fromThumbnail */, stackVr);
-            }
+            // If there is no thumbnail transition, but is launching from home into recents, then
+            // use a quick home transition
+            ActivityOptions opts = hasRecentTasks
+                    ? getHomeTransitionActivityOptions()
+                    : getUnknownTransitionActivityOptions();
+            startRecentsActivity(opts);
         }
         mLastToggleTime = SystemClock.elapsedRealtime();
     }
@@ -935,25 +894,7 @@
     /**
      * Starts the recents activity.
      */
-    private void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
-                ActivityOptions opts, boolean fromHome, boolean fromSearchHome,
-                boolean fromThumbnail, TaskStackLayoutAlgorithm.VisibilityReport vr) {
-        // Update the configuration based on the launch options
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        launchState.launchedFromHome = fromSearchHome || fromHome;
-        launchState.launchedFromSearchHome = fromSearchHome;
-        launchState.launchedFromApp = fromThumbnail || mLaunchedWhileDocking;
-        launchState.launchedFromAppDocked = mLaunchedWhileDocking;
-        launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
-        launchState.launchedWithAltTab = mTriggeredFromAltTab;
-        launchState.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
-        launchState.launchedNumVisibleTasks = vr.numVisibleTasks;
-        launchState.launchedNumVisibleThumbnails = vr.numVisibleThumbnails;
-        launchState.launchedHasConfigurationChanged = false;
-        launchState.launchedViaDragGesture = mDraggingInRecents;
-        launchState.launchedWhileDocking = mLaunchedWhileDocking;
-
+    private void startRecentsActivity(ActivityOptions opts) {
         Intent intent = new Intent();
         intent.setClassName(RECENTS_PACKAGE, RECENTS_ACTIVITY);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -965,7 +906,6 @@
         } else {
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
-        mCanReuseTaskStackViews = true;
         EventBus.getDefault().send(new RecentsActivityStartingEvent());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java
similarity index 80%
rename from packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
rename to packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java
index 98c0a69..4738eed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
 
 package com.android.systemui.recents.events.activity;
@@ -19,8 +19,7 @@
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the history is to be cleared
+ * Sent when an app transition has finished playing.
  */
-public class ClearHistoryEvent extends EventBus.AnimatedEvent {
-    // Simple event
+public class AppTransitionFinishedEvent extends EventBus.Event {
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppWidgetProviderChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppWidgetProviderChangedEvent.java
deleted file mode 100644
index 52cfe18..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppWidgetProviderChangedEvent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.RecentsAppWidgetHost;
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent by the {@link RecentsAppWidgetHost} whenever the search provider widget changes, and
- * subscribers can update accordingly.
- */
-public class AppWidgetProviderChangedEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
index 0ad4681..c234c34 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
@@ -22,5 +22,10 @@
  * This is sent when the Recents activity configuration has changed.
  */
 public class ConfigurationChangedEvent extends EventBus.AnimatedEvent {
-    // Simple event
+
+    public final boolean fromMultiWindow;
+
+    public ConfigurationChangedEvent(boolean fromMultiWindow) {
+        this.fromMultiWindow = fromMultiWindow;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java
similarity index 74%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
copy to packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java
index 98c0a69..32d9a70 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java
@@ -11,16 +11,15 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
 
 package com.android.systemui.recents.events.activity;
 
-import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.EventBus.Event;
 
 /**
- * This is sent when the history is to be cleared
+ * Sent when the window animation has started when docking a task
  */
-public class ClearHistoryEvent extends EventBus.AnimatedEvent {
-    // Simple event
+public class DockedFirstAnimationFrameEvent extends Event {
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
similarity index 62%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
copy to packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
index aaf77af..cdcabf0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
 
 package com.android.systemui.recents.events.activity;
@@ -19,10 +19,16 @@
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the history view button is clicked.
+ * Sent when recents received the information that an activity got forced resizable, and we need
+ * to inform the user about that.
  */
-public class ToggleHistoryEvent extends EventBus.AnimatedEvent {
+public class ForcedResizableEvent extends EventBus.Event {
 
-    // Simple event
+    public final String packageName;
+    public final int taskId;
 
+    public ForcedResizableEvent(String packageName, int taskId) {
+        this.packageName = packageName;
+        this.taskId = taskId;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryButtonEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryButtonEvent.java
deleted file mode 100644
index 6c767e4..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryButtonEvent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the history view button should be hidden.
- */
-public class HideHistoryButtonEvent extends EventBus.Event {
-    // Simple event
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryEvent.java
deleted file mode 100644
index bacf3bd..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.events.activity;
-
-import com.android.systemui.recents.events.EventBus;
-
-/**
- * This is sent when the history view will be closed.
- */
-public class HideHistoryEvent extends EventBus.Event {
-
-    public final boolean animate;
-
-    public HideHistoryEvent(boolean animate) {
-        this.animate = animate;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideStackActionButtonEvent.java
similarity index 85%
rename from packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryEvent.java
rename to packages/SystemUI/src/com/android/systemui/recents/events/activity/HideStackActionButtonEvent.java
index 469f336..e02fb14 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideStackActionButtonEvent.java
@@ -19,10 +19,8 @@
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the history view button is clicked.
+ * This is sent when the stack action button should be hidden.
  */
-public class ShowHistoryEvent extends EventBus.Event {
-
+public class HideStackActionButtonEvent extends EventBus.Event {
     // Simple event
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryButtonEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowStackActionButtonEvent.java
similarity index 75%
rename from packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryButtonEvent.java
rename to packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowStackActionButtonEvent.java
index ae803ea..d81f89c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryButtonEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowStackActionButtonEvent.java
@@ -19,14 +19,14 @@
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the history view button should be shown.
+ * This is sent when the stack action view button should be shown.
  */
-public class ShowHistoryButtonEvent extends EventBus.Event {
+public class ShowStackActionButtonEvent extends EventBus.Event {
 
-    // Whether or not to translate the history button when showing it
+    // Whether or not to translate the stack action button when showing it
     public final boolean translate;
 
-    public ShowHistoryButtonEvent(boolean translate) {
+    public ShowStackActionButtonEvent(boolean translate) {
         this.translate = translate;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
deleted file mode 100644
index 16385c9..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.history;
-
-import android.app.ActivityOptions;
-import android.content.Context;
-import android.support.v7.widget.RecyclerView;
-import android.text.format.DateFormat;
-import android.util.SparseIntArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.HideHistoryButtonEvent;
-import com.android.systemui.recents.events.activity.HideHistoryEvent;
-import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.recents.model.RecentsTaskLoader;
-import com.android.systemui.recents.model.Task;
-import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.recents.views.AnimationProps;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-
-
-/**
- * An adapter for the list of recent tasks in the history view.
- */
-public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAdapter.ViewHolder> {
-
-    private static final String TAG = "RecentsHistoryView";
-    private static final boolean DEBUG = false;
-
-    static final int DATE_ROW_VIEW_TYPE = 0;
-    static final int TASK_ROW_VIEW_TYPE = 1;
-
-    /**
-     * View holder implementation. The {@param TaskCallbacks} are only called for TaskRow view
-     * holders.
-     */
-    public static class ViewHolder extends RecyclerView.ViewHolder implements Task.TaskCallbacks {
-        public final View content;
-
-        private Task mTask;
-
-        public ViewHolder(View content) {
-            super(content);
-            this.content = content;
-        }
-
-        /**
-         * Binds this view holder to the given task.
-         */
-        public void bindToTask(Task newTask) {
-            unbindFromTask();
-            mTask = newTask;
-            mTask.addCallback(this);
-        }
-
-        /**
-         * Unbinds this view holder from the
-         */
-        public void unbindFromTask() {
-            if (mTask != null) {
-                mTask.removeCallback(this);
-                mTask = null;
-            }
-        }
-
-        @Override
-        public void onTaskDataLoaded(Task task) {
-            // This callback is only made for TaskRow view holders
-            ImageView iv = (ImageView) content.findViewById(R.id.icon);
-            iv.setImageDrawable(task.icon);
-            iv.animate()
-                    .alpha(1f)
-                    .setDuration(100)
-                    .start();
-        }
-
-        @Override
-        public void onTaskDataUnloaded() {
-            // This callback is only made for TaskRow view holders
-            ImageView iv = (ImageView) content.findViewById(R.id.icon);
-            iv.setImageBitmap(null);
-            iv.animate().cancel();
-        }
-
-        @Override
-        public void onTaskStackIdChanged() {
-            // Do nothing, this callback is only made for TaskRow view holders
-        }
-    }
-
-    /**
-     * A single row of content.
-     */
-    interface Row {
-        int getViewType();
-    }
-
-    /**
-     * A date row.
-     */
-    static class DateRow implements Row {
-
-        public final String date;
-
-        public DateRow(String date) {
-            this.date = date;
-        }
-
-        @Override
-        public int getViewType() {
-            return RecentsHistoryAdapter.DATE_ROW_VIEW_TYPE;
-        }
-    }
-
-    /**
-     * A task row.
-     */
-    static class TaskRow implements Row, View.OnClickListener {
-
-        public final Task task;
-        public final int dateKey;
-
-        public TaskRow(Task task, int dateKey) {
-            this.task = task;
-            this.dateKey = dateKey;
-        }
-
-        @Override
-        public void onClick(View v) {
-            SystemServicesProxy ssp = Recents.getSystemServices();
-            ssp.startActivityFromRecents(v.getContext(), task.key.id, task.title,
-                    ActivityOptions.makeBasic());
-
-            MetricsLogger.action(v.getContext(), MetricsEvent.ACTION_OVERVIEW_SELECT,
-                    task.key.getComponent().toString());
-        }
-
-        @Override
-        public int getViewType() {
-            return RecentsHistoryAdapter.TASK_ROW_VIEW_TYPE;
-        }
-    }
-
-    private Context mContext;
-    private LayoutInflater mLayoutInflater;
-    private final List<Row> mRows = new ArrayList<>();
-    private final SparseIntArray mTaskRowCount = new SparseIntArray();
-    private TaskStack mStack;
-
-    public RecentsHistoryAdapter(Context context) {
-        mLayoutInflater = LayoutInflater.from(context);
-    }
-
-    /**
-     * Updates this adapter with the given tasks.
-     */
-    public void updateTasks(Context context, TaskStack stack) {
-        mContext = context;
-        mStack = stack;
-
-        final Locale l = context.getResources().getConfiguration().locale;
-        final String dateFormatStr = DateFormat.getBestDateTimePattern(l, "EEEEMMMMd");
-        final List<Task> tasksMostRecent = new ArrayList<>(stack.getHistoricalTasks());
-        Collections.reverse(tasksMostRecent);
-        int prevDateKey = -1;
-        int taskCount = tasksMostRecent.size();
-        mRows.clear();
-        mTaskRowCount.clear();
-        Calendar cal = Calendar.getInstance(l);
-        for (int i = 0; i < taskCount; i++) {
-            Task task = tasksMostRecent.get(i);
-            if (task.isFreeformTask()) {
-                continue;
-            }
-
-            cal.setTimeInMillis(task.key.lastActiveTime);
-            int dateKey = Objects.hash(cal.get(Calendar.YEAR), cal.get(Calendar.DAY_OF_YEAR));
-            if (dateKey != prevDateKey) {
-                prevDateKey = dateKey;
-                mRows.add(new DateRow(DateFormat.format(dateFormatStr, cal).toString()));
-            }
-            mRows.add(new TaskRow(task, dateKey));
-            mTaskRowCount.put(dateKey, mTaskRowCount.get(dateKey, 0) + 1);
-        }
-        notifyDataSetChanged();
-    }
-
-    /**
-     * Removes historical tasks belonging to the specified package and user. We do not need to
-     * remove the task from the TaskStack since the TaskStackView will also receive this event.
-     */
-    public void removeTasks(String packageName, int userId) {
-        for (int i = mRows.size() - 1; i >= 0; i--) {
-            Row row = mRows.get(i);
-            if (row.getViewType() == TASK_ROW_VIEW_TYPE) {
-                TaskRow taskRow = (TaskRow) row;
-                Task task = taskRow.task;
-                String taskPackage = task.key.getComponent().getPackageName();
-                if (task.key.userId == userId && taskPackage.equals(packageName)) {
-                    i = removeTaskRow(i);
-                }
-            }
-        }
-        if (mRows.isEmpty()) {
-            dismissHistory();
-        }
-    }
-
-    /**
-     * Removes all historical tasks.
-     */
-    public void removeAllTasks() {
-        for (int i = mRows.size() - 1; i >= 0; i--) {
-            Row row = mRows.get(i);
-            if (row.getViewType() == TASK_ROW_VIEW_TYPE) {
-                TaskRow taskRow = (TaskRow) row;
-                Task task = taskRow.task;
-                mStack.removeTask(task, AnimationProps.IMMEDIATE, false /* fromDockGesture */);
-                EventBus.getDefault().send(new DeleteTaskDataEvent(task));
-                i = removeTaskRow(i);
-            }
-        }
-        dismissHistory();
-    }
-
-    /**
-     * Returns the row at the given {@param position}.
-     */
-    public Row getRow(int position) {
-        return mRows.get(position);
-    }
-
-    @Override
-    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-        switch (viewType) {
-            case DATE_ROW_VIEW_TYPE:
-                return new ViewHolder(mLayoutInflater.inflate(R.layout.recents_history_date, parent,
-                        false));
-            case TASK_ROW_VIEW_TYPE:
-                return new ViewHolder(mLayoutInflater.inflate(R.layout.recents_history_task, parent,
-                        false));
-            default:
-                return new ViewHolder(null);
-        }
-    }
-
-    @Override
-    public void onBindViewHolder(ViewHolder holder, int position) {
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-
-        Row row = mRows.get(position);
-        int viewType = row.getViewType();
-        switch (viewType) {
-            case DATE_ROW_VIEW_TYPE: {
-                TextView tv = (TextView) holder.content;
-                tv.setText(((DateRow) row).date);
-                break;
-            }
-            case TASK_ROW_VIEW_TYPE: {
-                TaskRow taskRow = (TaskRow) row;
-                TextView tv = (TextView) holder.content.findViewById(R.id.description);
-                tv.setText(taskRow.task.title);
-                ImageView iv = (ImageView) holder.content.findViewById(R.id.icon);
-                iv.setAlpha(0f);
-                holder.content.setOnClickListener(taskRow);
-
-                holder.bindToTask(taskRow.task);
-                loader.loadTaskData(taskRow.task, false /* fetchAndInvalidateThumbnails */);
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void onViewRecycled(ViewHolder holder) {
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        int position = holder.getAdapterPosition();
-        if (position != RecyclerView.NO_POSITION) {
-            Row row = mRows.get(position);
-            int viewType = row.getViewType();
-            if (viewType == TASK_ROW_VIEW_TYPE) {
-                TaskRow taskRow = (TaskRow) row;
-                loader.unloadTaskData(taskRow.task);
-                holder.unbindFromTask();
-            }
-        }
-    }
-
-    @Override
-    public boolean onFailedToRecycleView(ViewHolder holder) {
-        // Always recycle views, even if it is animating
-        onViewRecycled(holder);
-        return true;
-    }
-
-    public void onTaskRemoved(Task task, int position) {
-        // Since this is removed from the history, we need to update the stack as well to ensure
-        // that the model is correct. Since the stack is hidden, we can update it immediately.
-        mStack.removeTask(task, AnimationProps.IMMEDIATE, false /* fromDockGesture */);
-        removeTaskRow(position);
-        if (mRows.isEmpty()) {
-            dismissHistory();
-        }
-    }
-
-    @Override
-    public int getItemCount() {
-        return mRows.size();
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mRows.get(position).getViewType();
-    }
-
-    /**
-     * Removes a task row, also removing the associated {@link DateRow} if there are no more tasks
-     * in that date group.
-     *
-     * @param position an adapter position of a task row such that 0 < position < num rows.
-     * @return the index of the last removed row
-     */
-    private int removeTaskRow(int position) {
-        // Remove the task at that row
-        TaskRow taskRow = (TaskRow) mRows.remove(position);
-        int numTasks = mTaskRowCount.get(taskRow.dateKey) - 1;
-        mTaskRowCount.put(taskRow.dateKey, numTasks);
-        notifyItemRemoved(position);
-
-        if (numTasks == 0) {
-            // If that was the last task row in the group, then remove the date as well
-            mRows.remove(position - 1);
-            mTaskRowCount.removeAt(mTaskRowCount.indexOfKey(taskRow.dateKey));
-            notifyItemRemoved(position - 1);
-            return position - 1;
-        } else {
-            return position;
-        }
-    }
-
-    /**
-     * Dismisses history back to the stack view.
-     */
-    private void dismissHistory() {
-        EventBus.getDefault().send(new HideHistoryEvent(true /* animate */));
-        EventBus.getDefault().send(new HideHistoryButtonEvent());
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryItemTouchCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryItemTouchCallbacks.java
deleted file mode 100644
index 3d1ea8e..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryItemTouchCallbacks.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.history;
-
-import android.content.Context;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.helper.ItemTouchHelper;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.systemui.recents.Constants;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
-
-
-/**
- * An item touch handler for items in the history view.
- */
-public class RecentsHistoryItemTouchCallbacks extends ItemTouchHelper.SimpleCallback {
-
-    private Context mContext;
-    private RecentsHistoryAdapter mAdapter;
-
-    public RecentsHistoryItemTouchCallbacks(Context context, RecentsHistoryAdapter adapter) {
-        super(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
-        mContext = context;
-        mAdapter = adapter;
-    }
-
-    @Override
-    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
-            RecyclerView.ViewHolder target) {
-        return false;
-    }
-
-    @Override
-    public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
-        int viewType = mAdapter.getItemViewType(viewHolder.getAdapterPosition());
-        switch (viewType) {
-            case RecentsHistoryAdapter.DATE_ROW_VIEW_TYPE:
-                // Disallow swiping
-                return 0;
-            default:
-                return super.getSwipeDirs(recyclerView, viewHolder);
-        }
-    }
-
-    @Override
-    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
-        int position = viewHolder.getAdapterPosition();
-        if (position != RecyclerView.NO_POSITION) {
-            RecentsHistoryAdapter.Row row = mAdapter.getRow(position);
-            RecentsHistoryAdapter.TaskRow taskRow = (RecentsHistoryAdapter.TaskRow) row;
-
-            // Remove the task from the system
-            EventBus.getDefault().send(new DeleteTaskDataEvent(taskRow.task));
-            mAdapter.onTaskRemoved(taskRow.task, position);
-
-            // Keep track of deletions by swiping within history
-            MetricsLogger.histogram(mContext, "overview_task_dismissed_source",
-                    Constants.Metrics.DismissSourceHistorySwipeGesture);
-            MetricsLogger.action(mContext, MetricsEvent.OVERVIEW_DISMISS,
-                    taskRow.task.key.getComponent().toString());
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
deleted file mode 100644
index 3c4adb2..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.recents.history;
-
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.helper.ItemTouchHelper;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.WindowInsets;
-import android.widget.LinearLayout;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsActivity;
-import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.ClearHistoryEvent;
-import com.android.systemui.recents.events.activity.PackagesChangedEvent;
-import com.android.systemui.recents.events.ui.ResetBackgroundScrimEvent;
-import com.android.systemui.recents.events.ui.UpdateBackgroundScrimEvent;
-import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.recents.views.AnimateableViewBounds;
-
-/**
- * A list of the recent tasks that are not in the stack.
- */
-public class RecentsHistoryView extends LinearLayout
-        implements ValueAnimator.AnimatorUpdateListener {
-
-    private static final float TRANSLATION_Y_PCT = 0.25f;
-    private static final float BG_SCRIM_ALPHA = 0.625f;
-
-    private RecyclerView mRecyclerView;
-    private RecentsHistoryAdapter mAdapter;
-    private RecentsHistoryItemTouchCallbacks mItemTouchHandler;
-    private AnimateableViewBounds mViewBounds;
-    private boolean mIsVisible;
-    private Rect mSystemInsets = new Rect();
-    private int mHeaderHeight;
-
-    private int mHistoryTransitionDuration;
-
-    public RecentsHistoryView(Context context) {
-        super(context);
-    }
-
-    public RecentsHistoryView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public RecentsHistoryView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public RecentsHistoryView(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        Resources res = context.getResources();
-        mAdapter = new RecentsHistoryAdapter(context);
-        mItemTouchHandler = new RecentsHistoryItemTouchCallbacks(context, mAdapter);
-        mHistoryTransitionDuration = res.getInteger(R.integer.recents_history_transition_duration);
-        mViewBounds = new AnimateableViewBounds(this, 0);
-        setOutlineProvider(mViewBounds);
-    }
-
-    /**
-     * Updates this history view with the recent tasks, and then shows it.
-     */
-    public void show(TaskStack stack, int stackHeight, View clearAllButton) {
-        setVisibility(View.VISIBLE);
-        setAlpha(0f);
-        setTranslationY(-stackHeight * TRANSLATION_Y_PCT);
-        animate()
-                .alpha(1f)
-                .translationY(0f)
-                .setDuration(mHistoryTransitionDuration)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .setUpdateListener(this)
-                .start();
-        clearAllButton.setVisibility(View.VISIBLE);
-        clearAllButton.setAlpha(0f);
-        clearAllButton.animate()
-                .alpha(1f)
-                .setDuration(mHistoryTransitionDuration)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .withLayer()
-                .start();
-        mAdapter.updateTasks(getContext(), stack);
-        mIsVisible = true;
-        EventBus.getDefault().send(new UpdateBackgroundScrimEvent(BG_SCRIM_ALPHA));
-
-        MetricsLogger.visible(mRecyclerView.getContext(), MetricsEvent.OVERVIEW_HISTORY);
-    }
-
-    /**
-     * Hides this history view.
-     */
-    public void hide(boolean animate, int stackHeight, final View clearAllButton) {
-        if (animate) {
-            animate()
-                    .alpha(0f)
-                    .translationY(-stackHeight * TRANSLATION_Y_PCT)
-                    .setDuration(mHistoryTransitionDuration)
-                    .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
-                    .setUpdateListener(this)
-                    .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            setVisibility(View.INVISIBLE);
-                        }
-                    })
-                    .start();
-            clearAllButton.animate()
-                    .alpha(0f)
-                    .translationY(0f)
-                    .setDuration(mHistoryTransitionDuration)
-                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                    .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            clearAllButton.setVisibility(View.INVISIBLE);
-                        }
-                    })
-                    .withLayer()
-                    .start();
-        } else {
-            setAlpha(0f);
-            setVisibility(View.INVISIBLE);
-            clearAllButton.setAlpha(0f);
-            clearAllButton.setVisibility(View.INVISIBLE);
-        }
-        mIsVisible = false;
-        EventBus.getDefault().send(new ResetBackgroundScrimEvent());
-
-        MetricsLogger.hidden(mRecyclerView.getContext(), MetricsEvent.OVERVIEW_HISTORY);
-    }
-
-    /**
-     * Updates the system insets of this history view to the provided values.
-     */
-    public void setSystemInsets(Rect systemInsets) {
-        mSystemInsets.set(systemInsets);
-        requestLayout();
-    }
-
-    /**
-     * Updates the header height to account for the history button bar.
-     */
-    public void setHeaderHeight(int height) {
-        mHeaderHeight = height;
-        requestLayout();
-    }
-
-    /**
-     * Returns whether this view is visible.
-     */
-    public boolean isVisible() {
-        return mIsVisible;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mRecyclerView = (RecyclerView) findViewById(R.id.list);
-        mRecyclerView.setAdapter(mAdapter);
-        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
-        mRecyclerView.getItemAnimator().setRemoveDuration(100);
-        ItemTouchHelper touchHelper = new ItemTouchHelper(mItemTouchHandler);
-        touchHelper.attachToRecyclerView(mRecyclerView);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-        int height = MeasureSpec.getSize(heightMeasureSpec);
-
-        // Pad the view to align the history with the stack layout
-        Rect taskStackBounds = new Rect();
-        config.getTaskStackBounds(new Rect(0, 0, width, height), mSystemInsets.top,
-                mSystemInsets.right, new Rect() /* searchBarSpaceBounds */, taskStackBounds);
-        int stackWidthPadding = (int) (config.taskStackWidthPaddingPct * taskStackBounds.width());
-        int stackHeightPadding = mContext.getResources().getDimensionPixelSize(
-                R.dimen.recents_stack_top_padding);
-        mRecyclerView.setPadding(stackWidthPadding + mSystemInsets.left,
-                stackHeightPadding + mSystemInsets.top + mHeaderHeight,
-                stackWidthPadding + mSystemInsets.right, mSystemInsets.bottom);
-
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
-        super.onAttachedToWindow();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        EventBus.getDefault().unregister(this);
-    }
-
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        setSystemInsets(insets.getSystemWindowInsets());
-        return insets;
-    }
-
-    @Override
-    public void onAnimationUpdate(ValueAnimator animation) {
-        // Clip the top of the view by the header bar height
-        int top = Math.max(0, (int) -getTranslationY()) + mSystemInsets.top + mHeaderHeight;
-        mViewBounds.setClipTop(top);
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-
-    /**** EventBus Events ****/
-
-    public final void onBusEvent(PackagesChangedEvent event) {
-        mAdapter.removeTasks(event.packageName, event.userId);
-    }
-
-    public final void onBusEvent(ClearHistoryEvent event) {
-        mAdapter.removeAllTasks();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 330d138..3b759c02 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -16,15 +16,18 @@
 
 package com.android.systemui.recents.misc;
 
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
+
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.ITaskStackListener;
-import android.appwidget.AppWidgetHost;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -34,6 +37,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -47,7 +51,10 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.Bundle;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.Looper;
+import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -57,10 +64,9 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.MutableBoolean;
-import android.util.Pair;
 import android.view.Display;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IDockedStackListener;
-import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowManager.KeyboardShortcutsReceiver;
 import android.view.WindowManagerGlobal;
@@ -68,11 +74,11 @@
 
 import com.android.internal.app.AssistUtils;
 import com.android.internal.os.BackgroundThread;
-import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.tv.RecentsTvImpl;
+import com.android.systemui.recents.model.ThumbnailData;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -80,12 +86,6 @@
 import java.util.List;
 import java.util.Random;
 
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.HOME_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
-
 /**
  * Acts as a shim around the real system services that we need to access data from, and provides
  * a point of injection when testing UI.
@@ -106,10 +106,11 @@
         sRecentsBlacklist.add("com.android.systemui.tv.pip.PipMenuActivity");
     }
 
+    private static SystemServicesProxy sSystemServicesProxy;
+
     AccessibilityManager mAccm;
     ActivityManager mAm;
     IActivityManager mIam;
-    AppWidgetManager mAwm;
     PackageManager mPm;
     IPackageManager mIpm;
     AssistUtils mAssistUtils;
@@ -128,12 +129,69 @@
     Paint mBgProtectionPaint;
     Canvas mBgProtectionCanvas;
 
+    private final Handler mHandler = new H();
+
+    /**
+     * An abstract class to track task stack changes.
+     * Classes should implement this instead of {@link android.app.ITaskStackListener}
+     * to reduce IPC calls from system services. These callbacks will be called on the main thread.
+     */
+    public abstract static class TaskStackListener {
+        public void onTaskStackChanged() { }
+        public void onActivityPinned() { }
+        public void onPinnedActivityRestartAttempt() { }
+        public void onPinnedStackAnimationEnded() { }
+        public void onActivityForcedResizable(String packageName, int taskId) { }
+    }
+
+    /**
+     * Implementation of {@link android.app.ITaskStackListener} to listen task stack changes from
+     * ActivityManagerNative.
+     * This simply passes callbacks to listeners through {@link H}.
+     * */
+    private ITaskStackListener.Stub mTaskStackListener = new ITaskStackListener.Stub() {
+        @Override
+        public void onTaskStackChanged() throws RemoteException {
+            mHandler.removeMessages(H.ON_TASK_STACK_CHANGED);
+            mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED);
+        }
+
+        @Override
+        public void onActivityPinned() throws RemoteException {
+            mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
+            mHandler.sendEmptyMessage(H.ON_ACTIVITY_PINNED);
+        }
+
+        @Override
+        public void onPinnedActivityRestartAttempt() throws RemoteException{
+            mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
+            mHandler.sendEmptyMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
+        }
+
+        @Override
+        public void onPinnedStackAnimationEnded() throws RemoteException {
+            mHandler.removeMessages(H.ON_PINNED_STACK_ANIMATION_ENDED);
+            mHandler.sendEmptyMessage(H.ON_PINNED_STACK_ANIMATION_ENDED);
+        }
+
+        @Override
+        public void onActivityForcedResizable(String packageName, int taskId)
+                throws RemoteException {
+            mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, 0, packageName)
+                    .sendToTarget();
+        }
+    };
+
+    /**
+     * List of {@link TaskStackListener} registered from {@link #registerTaskStackListener}.
+     */
+    private List<TaskStackListener> mTaskStackListeners = new ArrayList<>();
+
     /** Private constructor */
-    public SystemServicesProxy(Context context) {
+    private SystemServicesProxy(Context context) {
         mAccm = AccessibilityManager.getInstance(context);
         mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         mIam = ActivityManagerNative.getDefault();
-        mAwm = AppWidgetManager.getInstance(context);
         mPm = context.getPackageManager();
         mIpm = AppGlobals.getPackageManager();
         mAssistUtils = new AssistUtils(context);
@@ -170,6 +228,20 @@
         }
     }
 
+    /**
+     * Returns the single instance of the {@link SystemServicesProxy}.
+     * This should only be called on the main thread.
+     */
+    public static SystemServicesProxy getInstance(Context context) {
+        if (!Looper.getMainLooper().isCurrentThread()) {
+            throw new RuntimeException("Must be called on the UI thread");
+        }
+        if (sSystemServicesProxy == null) {
+            sSystemServicesProxy = new SystemServicesProxy(context);
+        }
+        return sSystemServicesProxy;
+    }
+
     /** Returns a list of the recents tasks */
     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId,
             boolean isTopTaskHome, ArraySet<Integer> quietProfileIds) {
@@ -329,13 +401,12 @@
     }
 
     /** Docks a task to the side of the screen and starts it. */
-    public void startTaskInDockedMode(Context context, View view, int taskId, int createMode) {
+    public void startTaskInDockedMode(int taskId, int createMode) {
         if (mIam == null) return;
 
         try {
             // TODO: Determine what animation we want for the incoming task
-            final ActivityOptions options = ActivityOptions.makeThumbnailAspectScaleUpAnimation(
-                    view, null, 0, 0, view.getWidth(), view.getHeight(), null, null);
+            final ActivityOptions options = ActivityOptions.makeBasic();
             options.setDockCreateMode(createMode);
             options.setLaunchStackId(DOCKED_STACK_ID);
             mIam.startActivityFromRecents(taskId, options.toBundle());
@@ -450,44 +521,47 @@
     }
 
     /** Returns the top task thumbnail for the given task id */
-    public Bitmap getTaskThumbnail(int taskId) {
+    public ThumbnailData getTaskThumbnail(int taskId) {
         if (mAm == null) return null;
+        ThumbnailData thumbnailData = new ThumbnailData();
 
         // If we are mocking, then just return a dummy thumbnail
         if (RecentsDebugFlags.Static.EnableMockTasks) {
-            Bitmap thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth, mDummyThumbnailHeight,
-                    Bitmap.Config.ARGB_8888);
-            thumbnail.eraseColor(0xff333333);
-            return thumbnail;
+            thumbnailData.thumbnail = Bitmap.createBitmap(mDummyThumbnailWidth,
+                    mDummyThumbnailHeight, Bitmap.Config.ARGB_8888);
+            thumbnailData.thumbnail.eraseColor(0xff333333);
+            return thumbnailData;
         }
 
-        Bitmap thumbnail = getThumbnail(taskId);
-        if (thumbnail != null) {
-            thumbnail.setHasAlpha(false);
+        getThumbnail(taskId, thumbnailData);
+        if (thumbnailData.thumbnail != null) {
+            thumbnailData.thumbnail.setHasAlpha(false);
             // We use a dumb heuristic for now, if the thumbnail is purely transparent in the top
             // left pixel, then assume the whole thumbnail is transparent. Generally, proper
             // screenshots are always composed onto a bitmap that has no alpha.
-            if (Color.alpha(thumbnail.getPixel(0, 0)) == 0) {
-                mBgProtectionCanvas.setBitmap(thumbnail);
-                mBgProtectionCanvas.drawRect(0, 0, thumbnail.getWidth(), thumbnail.getHeight(),
-                        mBgProtectionPaint);
+            if (Color.alpha(thumbnailData.thumbnail.getPixel(0, 0)) == 0) {
+                mBgProtectionCanvas.setBitmap(thumbnailData.thumbnail);
+                mBgProtectionCanvas.drawRect(0, 0, thumbnailData.thumbnail.getWidth(),
+                        thumbnailData.thumbnail.getHeight(), mBgProtectionPaint);
                 mBgProtectionCanvas.setBitmap(null);
                 Log.e(TAG, "Invalid screenshot detected from getTaskThumbnail()");
             }
         }
-        return thumbnail;
+        return thumbnailData;
     }
 
     /**
      * Returns a task thumbnail from the activity manager
      */
-    public Bitmap getThumbnail(int taskId) {
+    public void getThumbnail(int taskId, ThumbnailData thumbnailDataOut) {
         if (mAm == null) {
-            return null;
+            return;
         }
 
         ActivityManager.TaskThumbnail taskThumbnail = mAm.getTaskThumbnail(taskId);
-        if (taskThumbnail == null) return null;
+        if (taskThumbnail == null) {
+            return;
+        }
 
         Bitmap thumbnail = taskThumbnail.mainThumbnail;
         ParcelFileDescriptor descriptor = taskThumbnail.thumbnailFileDescriptor;
@@ -501,7 +575,8 @@
             } catch (IOException e) {
             }
         }
-        return thumbnail;
+        thumbnailDataOut.thumbnail = thumbnail;
+        thumbnailDataOut.thumbnailInfo = taskThumbnail.thumbnailInfo;
     }
 
     /**
@@ -785,89 +860,6 @@
     }
 
     /**
-     * Returns the current search widget id.
-     */
-    public int getSearchAppWidgetId(Context context) {
-        return Prefs.getInt(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_ID, -1);
-    }
-
-    /**
-     * Returns the current search widget info, binding a new one if necessary.
-     */
-    public AppWidgetProviderInfo getOrBindSearchAppWidget(Context context, AppWidgetHost host) {
-        int searchWidgetId = Prefs.getInt(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_ID, -1);
-        AppWidgetProviderInfo searchWidgetInfo = mAwm.getAppWidgetInfo(searchWidgetId);
-        AppWidgetProviderInfo resolvedSearchWidgetInfo = resolveSearchAppWidget();
-
-        // Return the search widget info if it hasn't changed
-        if (searchWidgetInfo != null && resolvedSearchWidgetInfo != null &&
-                searchWidgetInfo.provider.equals(resolvedSearchWidgetInfo.provider)) {
-            if (Prefs.getString(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_PACKAGE, null) == null) {
-                Prefs.putString(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_PACKAGE,
-                        searchWidgetInfo.provider.getPackageName());
-            }
-            return searchWidgetInfo;
-        }
-
-        // Delete the old widget
-        if (searchWidgetId != -1) {
-            host.deleteAppWidgetId(searchWidgetId);
-        }
-
-        // And rebind a new search widget
-        if (resolvedSearchWidgetInfo != null) {
-            Pair<Integer, AppWidgetProviderInfo> widgetInfo = bindSearchAppWidget(host,
-                    resolvedSearchWidgetInfo);
-            if (widgetInfo != null) {
-                Prefs.putInt(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_ID, widgetInfo.first);
-                Prefs.putString(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_PACKAGE,
-                        widgetInfo.second.provider.getPackageName());
-                return widgetInfo.second;
-            }
-        }
-
-        // If we fall through here, then there is no resolved search widget, so clear the state
-        Prefs.remove(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_ID);
-        Prefs.remove(context, Prefs.Key.OVERVIEW_SEARCH_APP_WIDGET_PACKAGE);
-        return null;
-    }
-
-    /**
-     * Returns the first Recents widget from the same package as the global assist activity.
-     */
-    public AppWidgetProviderInfo resolveSearchAppWidget() {
-        if (mAssistComponent == null) return null;
-        List<AppWidgetProviderInfo> widgets = mAwm.getInstalledProviders(
-                AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
-        for (AppWidgetProviderInfo info : widgets) {
-            if (info.provider.getPackageName().equals(mAssistComponent.getPackageName())) {
-                return info;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Resolves and binds the search app widget that is to appear in the recents.
-     */
-    private Pair<Integer, AppWidgetProviderInfo> bindSearchAppWidget(AppWidgetHost host,
-            AppWidgetProviderInfo resolvedSearchWidgetInfo) {
-        if (mAwm == null) return null;
-        if (mAssistComponent == null) return null;
-
-        // Allocate a new widget id and try and bind the app widget (if that fails, then just skip)
-        int searchWidgetId = host.allocateAppWidgetId();
-        Bundle opts = new Bundle();
-        opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
-                AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
-        if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, resolvedSearchWidgetInfo.provider, opts)) {
-            host.deleteAppWidgetId(searchWidgetId);
-            return null;
-        }
-        return new Pair<>(searchWidgetId, resolvedSearchWidgetInfo);
-    }
-
-    /**
      * Returns whether touch exploration is currently enabled.
      */
     public boolean isTouchExplorationEnabled() {
@@ -916,28 +908,40 @@
      * Returns the smallest width/height.
      */
     public int getDeviceSmallestWidth() {
-        if (mWm == null) return 0;
+        if (mDisplay == null) return 0;
 
         Point smallestSizeRange = new Point();
         Point largestSizeRange = new Point();
-        mWm.getDefaultDisplay().getCurrentSizeRange(smallestSizeRange, largestSizeRange);
+        mDisplay.getCurrentSizeRange(smallestSizeRange, largestSizeRange);
         return smallestSizeRange.x;
     }
 
     /**
-     * Returns the display rect.
+     * Returns the current display rect in the current display orientation.
      */
     public Rect getDisplayRect() {
         Rect displayRect = new Rect();
-        if (mWm == null) return displayRect;
+        if (mDisplay == null) return displayRect;
 
         Point p = new Point();
-        mWm.getDefaultDisplay().getRealSize(p);
+        mDisplay.getRealSize(p);
         displayRect.set(0, 0, p.x, p.y);
         return displayRect;
     }
 
     /**
+     * Returns the current display orientation.
+     */
+    public int getDisplayOrientation() {
+        // Because of multi-window, the configuration orientation does not necessarily reflect the
+        // orientation of the display, instead we just use the display's real-size.
+        Rect displayRect = getDisplayRect();
+        return displayRect.width() > displayRect.height()
+                ? Configuration.ORIENTATION_LANDSCAPE
+                : Configuration.ORIENTATION_PORTRAIT;
+    }
+
+    /**
      * Returns the window rect for the RecentsActivity, based on the dimensions of the home stack.
      */
     public Rect getWindowRect() {
@@ -982,14 +986,21 @@
         }
     }
 
-    /** Registers a task stack listener with the system. */
-    public void registerTaskStackListener(ITaskStackListener listener) {
+    /**
+     * Registers a task stack listener with the system.
+     * This should be called on the main thread.
+     */
+    public void registerTaskStackListener(TaskStackListener listener) {
         if (mIam == null) return;
 
-        try {
-            mIam.registerTaskStackListener(listener);
-        } catch (Exception e) {
-            e.printStackTrace();
+        mTaskStackListeners.add(listener);
+        if (mTaskStackListeners.size() == 1) {
+            // Register mTaskStackListener to IActivityManager only once if needed.
+            try {
+                mIam.registerTaskStackListener(mTaskStackListener);
+            } catch (Exception e) {
+                Log.w(TAG, "Failed to call registerTaskStackListener", e);
+            }
         }
     }
 
@@ -1026,8 +1037,9 @@
         return dividerWindowWidth - 2 * dividerInsets;
     }
 
-    public void requestKeyboardShortcuts(Context context, KeyboardShortcutsReceiver receiver) {
-        mWm.requestAppKeyboardShortcuts(receiver);
+    public void requestKeyboardShortcuts(
+            Context context, KeyboardShortcutsReceiver receiver, int deviceId) {
+        mWm.requestAppKeyboardShortcuts(receiver, deviceId);
     }
 
     public void getStableInsets(Rect outStableInsets) {
@@ -1039,4 +1051,71 @@
             e.printStackTrace();
         }
     }
+
+    public void overridePendingAppTransitionMultiThumbFuture(
+            IAppTransitionAnimationSpecsFuture future, IRemoteCallback animStartedListener,
+            boolean scaleUp) {
+        try {
+            WindowManagerGlobal.getWindowManagerService()
+                    .overridePendingAppTransitionMultiThumbFuture(future, animStartedListener,
+                            scaleUp);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to override transition: " + e);
+        }
+    }
+
+    /**
+     * Returns whether the device has a transposed nav bar (on the right of the screen) in the
+     * current display orientation.
+     */
+    public boolean hasTransposedNavBar() {
+        Rect insets = new Rect();
+        getStableInsets(insets);
+        return insets.right > 0;
+    }
+
+    private final class H extends Handler {
+        private static final int ON_TASK_STACK_CHANGED = 1;
+        private static final int ON_ACTIVITY_PINNED = 2;
+        private static final int ON_PINNED_ACTIVITY_RESTART_ATTEMPT = 3;
+        private static final int ON_PINNED_STACK_ANIMATION_ENDED = 4;
+        private static final int ON_ACTIVITY_FORCED_RESIZABLE = 5;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case ON_TASK_STACK_CHANGED: {
+                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                        mTaskStackListeners.get(i).onTaskStackChanged();
+                    }
+                    break;
+                }
+                case ON_ACTIVITY_PINNED: {
+                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                        mTaskStackListeners.get(i).onActivityPinned();
+                    }
+                    break;
+                }
+                case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
+                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                        mTaskStackListeners.get(i).onPinnedActivityRestartAttempt();
+                    }
+                    break;
+                }
+                case ON_PINNED_STACK_ANIMATION_ENDED: {
+                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                        mTaskStackListeners.get(i).onPinnedStackAnimationEnded();
+                    }
+                    break;
+                }
+                case ON_ACTIVITY_FORCED_RESIZABLE: {
+                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                        mTaskStackListeners.get(i).onActivityForcedResizable(
+                                (String) msg.obj, msg.arg1);
+                    }
+                    break;
+                }
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index 72b1cab..e28612a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.annotation.FloatRange;
+import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -26,6 +27,7 @@
 import android.util.ArraySet;
 import android.util.IntProperty;
 import android.util.Property;
+import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewParent;
 
@@ -67,6 +69,8 @@
 
     public static final RectFEvaluator RECTF_EVALUATOR = new RectFEvaluator();
 
+    public static final Rect EMPTY_RECT = new Rect();
+
     /**
      * @return the first parent walking up the view hierarchy that has the given class type.
      *
@@ -232,4 +236,11 @@
             transforms.subList(taskCount, taskTransformCount).clear();
         }
     }
+
+    /**
+     * Used for debugging, converts DP to PX.
+     */
+    public static float dpToPx(Resources res, float dp) {
+        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 6ae07fc..76ca6ca 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -39,7 +39,6 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Formatter;
 import java.util.List;
 
 
@@ -161,8 +160,15 @@
                 long parentTaskLastActiveTime = parentTask != null
                         ? parentTask.lastActiveTime
                         : prevLastActiveTime;
-                t.lastActiveTime = parentTaskLastActiveTime +
-                        affiliatedTaskCounts.get(t.affiliatedTaskId, 0) + 1;
+                if (RecentsDebugFlags.Static.EnableAffiliatedTaskGroups) {
+                    t.lastActiveTime = parentTaskLastActiveTime +
+                            affiliatedTaskCounts.get(t.affiliatedTaskId, 0) + 1;
+                } else {
+                    if (t.lastActiveTime == 0) {
+                        t.lastActiveTime = parentTaskLastActiveTime -
+                                affiliatedTaskCounts.get(t.affiliatedTaskId, 0) - 1;
+                    }
+                }
             }
 
             // Compose the task key
@@ -196,13 +202,12 @@
             // Add the task to the stack
             Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon,
                     thumbnail, title, contentDescription, dismissDescription, activityColor,
-                    backgroundColor, !isStackTask, isLaunchTarget, isSystemApp, t.isDockable,
+                    backgroundColor, isLaunchTarget, isStackTask, isSystemApp, t.isDockable,
                     t.bounds, t.taskDescription);
 
             allTasks.add(task);
             affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1);
             affiliatedTasks.put(taskKey.id, taskKey);
-
             prevLastActiveTime = t.lastActiveTime;
         }
         if (newLastStackActiveTime != -1) {
@@ -241,8 +246,8 @@
 
             if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
                 if (task.icon == null) {
-                    task.icon = loader.getAndUpdateActivityIcon(taskKey, task.taskDescription,
-                            res, true);
+                    task.icon = loader.getAndUpdateActivityIcon(taskKey, task.taskDescription, res,
+                            true);
                 }
             }
             if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
@@ -273,7 +278,7 @@
     }
 
     /**
-     * Returns whether this task is considered a task to be shown in the history.
+     * Returns whether this task is too old to be shown.
      */
     private boolean isHistoricalTask(ActivityManager.RecentTaskInfo t) {
         return t.lastActiveTime < (System.currentTimeMillis() - SESSION_BEGIN_TIME);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index ee4d95e..82c81ae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -95,7 +95,7 @@
 
     TaskResourceLoadQueue mLoadQueue;
     TaskKeyLruCache<Drawable> mIconCache;
-    TaskKeyLruCache<Bitmap> mThumbnailCache;
+    TaskKeyLruCache<ThumbnailData> mThumbnailCache;
     Bitmap mDefaultThumbnail;
     BitmapDrawable mDefaultIcon;
 
@@ -104,7 +104,7 @@
 
     /** Constructor, creates a new loading thread that loads task resources in the background */
     public BackgroundTaskLoader(TaskResourceLoadQueue loadQueue,
-            TaskKeyLruCache<Drawable> iconCache, TaskKeyLruCache<Bitmap> thumbnailCache,
+            TaskKeyLruCache<Drawable> iconCache, TaskKeyLruCache<ThumbnailData> thumbnailCache,
             Bitmap defaultThumbnail, BitmapDrawable defaultIcon) {
         mLoadQueue = loadQueue;
         mIconCache = iconCache;
@@ -165,7 +165,7 @@
                     final Task t = mLoadQueue.nextTask();
                     if (t != null) {
                         Drawable cachedIcon = mIconCache.get(t.key);
-                        Bitmap cachedThumbnail = mThumbnailCache.get(t.key);
+                        ThumbnailData cachedThumbnailData = mThumbnailCache.get(t.key);
 
                         // Load the icon if it is stale or we haven't cached one yet
                         if (cachedIcon == null) {
@@ -190,30 +190,32 @@
                             mIconCache.put(t.key, cachedIcon);
                         }
                         // Load the thumbnail if it is stale or we haven't cached one yet
-                        if (cachedThumbnail == null) {
+                        if (cachedThumbnailData == null) {
                             if (config.svelteLevel < RecentsConfiguration.SVELTE_DISABLE_LOADING) {
                                 if (DEBUG) Log.d(TAG, "Loading thumbnail: " + t.key);
-                                cachedThumbnail = ssp.getTaskThumbnail(t.key.id);
+                                cachedThumbnailData = ssp.getTaskThumbnail(t.key.id);
                             }
-                            if (cachedThumbnail == null) {
-                                cachedThumbnail = mDefaultThumbnail;
+
+                            if (cachedThumbnailData.thumbnail == null) {
+                                cachedThumbnailData.thumbnail = mDefaultThumbnail;
                             }
+
                             // When svelte, we trim the memory to just the visible thumbnails when
                             // leaving, so don't thrash the cache as the user scrolls (just load
                             // them from scratch each time)
                             if (config.svelteLevel < RecentsConfiguration.SVELTE_LIMIT_CACHE) {
-                                mThumbnailCache.put(t.key, cachedThumbnail);
+                                mThumbnailCache.put(t.key, cachedThumbnailData);
                             }
                         }
                         if (!mCancelled) {
                             // Notify that the task data has changed
                             final Drawable newIcon = cachedIcon;
-                            final Bitmap newThumbnail = cachedThumbnail == mDefaultThumbnail
-                                    ? null : cachedThumbnail;
+                            final ThumbnailData newThumbnailData = cachedThumbnailData;
                             mMainThreadHandler.post(new Runnable() {
                                 @Override
                                 public void run() {
-                                    t.notifyTaskDataLoaded(newThumbnail, newIcon);
+                                    t.notifyTaskDataLoaded(newThumbnailData.thumbnail, newIcon,
+                                            newThumbnailData.thumbnailInfo);
                                 }
                             });
                         }
@@ -252,7 +254,7 @@
     // package in the cache has been updated, so that we may remove it.
     private final LruCache<ComponentName, ActivityInfo> mActivityInfoCache;
     private final TaskKeyLruCache<Drawable> mIconCache;
-    private final TaskKeyLruCache<Bitmap> mThumbnailCache;
+    private final TaskKeyLruCache<ThumbnailData> mThumbnailCache;
     private final TaskKeyLruCache<String> mActivityLabelCache;
     private final TaskKeyLruCache<String> mContentDescriptionCache;
     private final TaskResourceLoadQueue mLoadQueue;
@@ -272,7 +274,9 @@
             new TaskKeyLruCache.EvictionCallback() {
         @Override
         public void onEntryEvicted(Task.TaskKey key) {
-            mActivityInfoCache.remove(key.getComponent());
+            if (key != null) {
+                mActivityInfoCache.remove(key.getComponent());
+            }
         }
     };
 
@@ -356,9 +360,16 @@
      */
     public void loadTaskData(Task t, boolean fetchAndInvalidateThumbnails) {
         Drawable icon = mIconCache.getAndInvalidateIfModified(t.key);
-        Bitmap thumbnail = mDefaultThumbnail;
+        Bitmap thumbnail = null;
+        ActivityManager.TaskThumbnailInfo thumbnailInfo = null;
         if (fetchAndInvalidateThumbnails) {
-            thumbnail = mThumbnailCache.getAndInvalidateIfModified(t.key);
+            ThumbnailData thumbnailData = mThumbnailCache.getAndInvalidateIfModified(t.key);
+            if (thumbnailData != null) {
+                thumbnail = thumbnailData.thumbnail;
+                thumbnailInfo = thumbnailData.thumbnailInfo;
+            }
+        } else {
+            thumbnail = mDefaultThumbnail;
         }
 
         // Grab the thumbnail/icon from the cache, if either don't exist, then trigger a reload and
@@ -368,7 +379,8 @@
         if (requiresLoad) {
             mLoadQueue.addTask(t);
         }
-        t.notifyTaskDataLoaded(thumbnail == mDefaultThumbnail ? null : thumbnail, icon);
+        t.notifyTaskDataLoaded(thumbnail == mDefaultThumbnail ? null : thumbnail, icon,
+                thumbnailInfo);
     }
 
     /** Releases the task resource data back into the pool. */
@@ -535,19 +547,19 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Return the cached thumbnail if it exists
-        Bitmap thumbnail = mThumbnailCache.getAndInvalidateIfModified(taskKey);
-        if (thumbnail != null) {
-            return thumbnail;
+        ThumbnailData thumbnailData = mThumbnailCache.getAndInvalidateIfModified(taskKey);
+        if (thumbnailData != null) {
+            return thumbnailData.thumbnail;
         }
 
         if (loadIfNotCached) {
             RecentsConfiguration config = Recents.getConfiguration();
             if (config.svelteLevel < RecentsConfiguration.SVELTE_DISABLE_LOADING) {
                 // Load the thumbnail from the system
-                thumbnail = ssp.getTaskThumbnail(taskKey.id);
-                if (thumbnail != null) {
-                    mThumbnailCache.put(taskKey, thumbnail);
-                    return thumbnail;
+                thumbnailData = ssp.getTaskThumbnail(taskKey.id);
+                if (thumbnailData.thumbnail != null) {
+                    mThumbnailCache.put(taskKey, thumbnailData);
+                    return thumbnailData.thumbnail;
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index b5a5949..d5d5aa0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -40,7 +40,7 @@
     /* Task callbacks */
     public interface TaskCallbacks {
         /* Notifies when a task has been bound */
-        public void onTaskDataLoaded(Task task);
+        public void onTaskDataLoaded(Task task, ActivityManager.TaskThumbnailInfo thumbnailInfo);
         /* Notifies when a task has been unbound */
         public void onTaskDataUnloaded();
         /* Notifies when a task's stack id has changed. */
@@ -161,7 +161,7 @@
     @ViewDebug.ExportedProperty(category="recents")
     public boolean isLaunchTarget;
     @ViewDebug.ExportedProperty(category="recents")
-    public boolean isHistorical;
+    public boolean isStackTask;
     @ViewDebug.ExportedProperty(category="recents")
     public boolean isSystemApp;
     @ViewDebug.ExportedProperty(category="recents")
@@ -176,7 +176,7 @@
     public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon,
                 Bitmap thumbnail, String title, String contentDescription,
                 String dismissDescription, int colorPrimary, int colorBackground,
-                boolean isHistorical, boolean isLaunchTarget, boolean isSystemApp,
+                boolean isLaunchTarget, boolean isStackTask, boolean isSystemApp,
                 boolean isDockable, Rect bounds, ActivityManager.TaskDescription taskDescription) {
         boolean isInAffiliationGroup = (affiliationTaskId != key.id);
         boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0);
@@ -195,7 +195,7 @@
         this.bounds = bounds;
         this.taskDescription = taskDescription;
         this.isLaunchTarget = isLaunchTarget;
-        this.isHistorical = isHistorical;
+        this.isStackTask = isStackTask;
         this.isSystemApp = isSystemApp;
         this.isDockable = isDockable;
     }
@@ -217,8 +217,9 @@
         this.colorBackground = o.colorBackground;
         this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
         this.bounds = o.bounds;
+        this.taskDescription = o.taskDescription;
         this.isLaunchTarget = o.isLaunchTarget;
-        this.isHistorical = o.isHistorical;
+        this.isStackTask = o.isStackTask;
         this.isSystemApp = o.isSystemApp;
         this.isDockable = o.isDockable;
     }
@@ -264,12 +265,13 @@
     }
 
     /** Notifies the callback listeners that this task has been loaded */
-    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon) {
+    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon,
+            ActivityManager.TaskThumbnailInfo thumbnailInfo) {
         this.icon = applicationIcon;
         this.thumbnail = thumbnail;
         int callbackCount = mCallbacks.size();
         for (int i = 0; i < callbackCount; i++) {
-            mCallbacks.get(i).onTaskDataLoaded(this);
+            mCallbacks.get(i).onTaskDataLoaded(this, thumbnailInfo);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 193bfff..5a2507d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -16,6 +16,16 @@
 
 package com.android.systemui.recents.model;
 
+import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
+import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
+
 import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
@@ -37,13 +47,13 @@
 import com.android.internal.policy.DockedDividerUtils;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.misc.NamedCounter;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
-import com.android.systemui.recents.views.DropTarget;
 import com.android.systemui.recents.views.AnimationProps;
+import com.android.systemui.recents.views.DropTarget;
+import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -51,16 +61,6 @@
 import java.util.List;
 import java.util.Random;
 
-import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
-import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
-
 
 /**
  * An interface for a task filter to query whether a particular task should show in a stack.
@@ -222,9 +222,9 @@
             Task newFrontMostTask, AnimationProps animation, boolean fromDockGesture);
 
         /**
-         * Notifies when a task has been removed from the history.
+         * Notifies when tasks in the stack have been updated.
          */
-        void onHistoryTaskRemoved(TaskStack stack, Task removedTask, AnimationProps animation);
+        void onStackTasksUpdated(TaskStack stack);
     }
 
     /**
@@ -375,29 +375,24 @@
          * {@param height}.
          */
         public Rect getDockedTaskStackBounds(int width, int height, int dividerSize, Rect insets,
-                Resources res) {
-            RecentsConfiguration config = Recents.getConfiguration();
-
+                TaskStackLayoutAlgorithm layoutAlgorithm, Resources res, Rect windowRectOut) {
             // Calculate the inverse docked task bounds
             boolean isHorizontalDivision =
                     res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
             int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
                     insets, width, height, dividerSize);
-            Rect newWindowBounds = new Rect();
             DockedDividerUtils.calculateBoundsForPosition(position,
-                    DockedDividerUtils.invertDockSide(dockSide), newWindowBounds, width, height,
+                    DockedDividerUtils.invertDockSide(dockSide), windowRectOut, width, height,
                     dividerSize);
 
             // Calculate the task stack bounds from the new window bounds
-            Rect searchBarSpaceBounds = new Rect();
             Rect taskStackBounds = new Rect();
             // If the task stack bounds is specifically under the dock area, then ignore the top
             // inset
             int top = dockArea.bottom < 1f
                     ? 0
                     : insets.top;
-            config.getTaskStackBounds(newWindowBounds, top, insets.right,
-                    searchBarSpaceBounds, taskStackBounds);
+            layoutAlgorithm.getTaskStackBounds(windowRectOut, top, insets.right, taskStackBounds);
             return taskStackBounds;
         }
     }
@@ -429,7 +424,6 @@
 
     ArrayList<Task> mRawTaskList = new ArrayList<>();
     FilteredTaskList mStackTaskList = new FilteredTaskList();
-    FilteredTaskList mHistoryTaskList = new FilteredTaskList();
     TaskStackCallbacks mCb;
 
     ArrayList<TaskGrouping> mGroups = new ArrayList<>();
@@ -440,29 +434,17 @@
         mStackTaskList.setFilter(new TaskFilter() {
             @Override
             public boolean acceptTask(SparseArray<Task> taskIdMap, Task t, int index) {
-                if (t.isAffiliatedTask()) {
-                    // If this task is affiliated with another parent in the stack, then the
-                    // historical state of this task depends on the state of the parent task
-                    Task parentTask = taskIdMap.get(t.affiliationTaskId);
-                    if (parentTask != null) {
-                        t = parentTask;
+                if (RecentsDebugFlags.Static.EnableAffiliatedTaskGroups) {
+                    if (t.isAffiliatedTask()) {
+                        // If this task is affiliated with another parent in the stack, then the
+                        // historical state of this task depends on the state of the parent task
+                        Task parentTask = taskIdMap.get(t.affiliationTaskId);
+                        if (parentTask != null) {
+                            t = parentTask;
+                        }
                     }
                 }
-                return !t.isHistorical;
-            }
-        });
-        mHistoryTaskList.setFilter(new TaskFilter() {
-            @Override
-            public boolean acceptTask(SparseArray<Task> taskIdMap, Task t, int index) {
-                if (t.isAffiliatedTask()) {
-                    // If this task is affiliated with another parent in the stack, then the
-                    // historical state of this task depends on the state of the parent task
-                    Task parentTask = taskIdMap.get(t.affiliationTaskId);
-                    if (parentTask != null) {
-                        t = parentTask;
-                    }
-                }
-                return t.isHistorical;
+                return t.isStackTask;
             }
         });
     }
@@ -523,12 +505,6 @@
                 mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask, animation,
                         fromDockGesture);
             }
-        } else if (mHistoryTaskList.contains(t)) {
-            removeTaskImpl(mHistoryTaskList, t);
-            if (mCb != null) {
-                // Notify that a task has been removed
-                mCb.onHistoryTaskRemoved(this, t, animation);
-            }
         }
         mRawTaskList.remove(t);
     }
@@ -586,31 +562,22 @@
         // Sort all the tasks to ensure they are ordered correctly
         Collections.sort(allTasks, FREEFORM_LAST_ACTIVE_TIME_COMPARATOR);
 
-        // Filter out the historical tasks from this new list
-        ArrayList<Task> stackTasks = new ArrayList<>();
-        ArrayList<Task> historyTasks = new ArrayList<>();
-        int newTaskCount = allTasks.size();
-        for (int i = 0; i < newTaskCount; i++) {
-            Task task = allTasks.get(i);
-            if (task.isHistorical) {
-                historyTasks.add(task);
-            } else {
-                stackTasks.add(task);
-            }
-        }
-
-        mStackTaskList.set(stackTasks);
-        mHistoryTaskList.set(historyTasks);
+        mStackTaskList.set(allTasks);
         mRawTaskList = allTasks;
 
+        // Update the affiliated groupings
+        createAffiliatedGroupings(context);
+
         // Only callback for the newly added tasks after this stack has been updated
         int addedTaskCount = addedTasks.size();
         for (int i = 0; i < addedTaskCount; i++) {
             mCb.onStackTaskAdded(this, addedTasks.get(i));
         }
 
-        // Update the affiliated groupings
-        createAffiliatedGroupings(context);
+        // Notify that the task stack has been updated
+        if (notifyStackChanges) {
+            mCb.onStackTasksUpdated(this);
+        }
     }
 
     /**
@@ -650,14 +617,6 @@
     }
 
     /**
-     * Returns the set of tasks that are inactive. These tasks will be presented in a separate
-     * history view.
-     */
-    public ArrayList<Task> getHistoricalTasks() {
-        return mHistoryTaskList.getTasks();
-    }
-
-    /**
      * Returns the set of "freeform" tasks in the stack.
      */
     public ArrayList<Task> getFreeformTasks() {
@@ -679,7 +638,6 @@
     public ArrayList<Task> computeAllTasksList() {
         ArrayList<Task> tasks = new ArrayList<>();
         tasks.addAll(mStackTaskList.getTasks());
-        tasks.addAll(mHistoryTaskList.getTasks());
         Collections.sort(tasks, LAST_ACTIVE_TIME_COMPARATOR);
         return tasks;
     }
@@ -927,10 +885,6 @@
         for (Task t : mStackTaskList.getTasks()) {
             str += "    " + t.toString() + "\n";
         }
-        str += "Historical Tasks(" + mHistoryTaskList.size() + "):\n";
-        for (Task t : mHistoryTaskList.getTasks()) {
-            str += "    " + t.toString() + "\n";
-        }
         return str;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/model/ThumbnailData.java
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
rename to packages/SystemUI/src/com/android/systemui/recents/model/ThumbnailData.java
index aaf77af..d0cdae5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/ThumbnailData.java
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.recents.events.activity;
+package com.android.systemui.recents.model;
 
-import com.android.systemui.recents.events.EventBus;
+import android.app.ActivityManager;
+import android.graphics.Bitmap;
 
 /**
- * This is sent when the history view button is clicked.
+ * Data for a single thumbnail.
  */
-public class ToggleHistoryEvent extends EventBus.AnimatedEvent {
-
-    // Simple event
-
+public class ThumbnailData {
+    public Bitmap thumbnail;
+    public ActivityManager.TaskThumbnailInfo thumbnailInfo;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index 960bd8c..134b90c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -15,6 +15,8 @@
  */
 package com.android.systemui.recents.tv;
 
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
 import android.app.Activity;
 import android.app.ActivityOptions;
 import android.content.Intent;
@@ -57,6 +59,7 @@
 import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.tv.pip.PipManager;
+import com.android.systemui.tv.pip.PipControlsView;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -77,8 +80,10 @@
     private boolean mIgnoreAltTabRelease;
 
     private RecentsTvView mRecentsView;
-    private View mPipView;
+    private PipControlsView mPipControlsView;
     private View mPipShadeView;
+    private AnimatorSet mPipControlsViewFadeInAnimator;
+    private AnimatorSet mPipControlsViewFadeOutAnimator;
     private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
     private FinishRecentsRunnable mFinishLaunchHomeRunnable;
 
@@ -95,10 +100,16 @@
         }
 
         @Override
-        public void onShowPipMenu() { }
+        public void onShowPipMenu() {
+            updatePipUI();
+        }
 
         @Override
-        public void onMoveToFullscreen() { }
+        public void onMoveToFullscreen() {
+            // Recents should be dismissed when PIP moves to fullscreen. If not, Recents will
+            // be unnecessarily shown in the scenario: PIP->Fullscreen->PIP.
+            dismissRecentsToLaunchTargetTaskOrHome();
+        }
 
         @Override
         public void onPipResizeAboutToStart() { }
@@ -106,7 +117,6 @@
         @Override
         public void onMediaControllerChanged() { }
     };
-    private boolean mHasPip;
 
     /**
      * A common Runnable to finish Recents by launching Home with an animation depending on the
@@ -126,15 +136,8 @@
         @Override
         public void run() {
             try {
-                RecentsActivityLaunchState launchState =
-                        Recents.getConfiguration().getLaunchState();
                 ActivityOptions opts = ActivityOptions.makeCustomAnimation(RecentsTvActivity.this,
-                        launchState.launchedFromSearchHome ?
-                                R.anim.recents_to_search_launcher_enter :
-                                R.anim.recents_to_launcher_enter,
-                        launchState.launchedFromSearchHome ?
-                                R.anim.recents_to_search_launcher_exit :
-                                R.anim.recents_to_launcher_exit);
+                        R.anim.recents_to_launcher_enter, R.anim.recents_to_launcher_exit);
                 startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
             } catch (Exception e) {
                 Log.e(TAG, getString(R.string.recents_launch_error_message, "Home"), e);
@@ -260,8 +263,22 @@
         mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-        mPipView = findViewById(R.id.pip);
+        mPipControlsView = (PipControlsView) findViewById(R.id.pip_controls);
+        mPipControlsView.setListener(new PipControlsView.Listener() {
+            @Override
+            public void onClosed() {
+                dismissRecentsToLaunchTargetTaskOrHome();
+            }
+        });
         mPipShadeView = findViewById(R.id.pip_shade);
+
+        mPipControlsViewFadeInAnimator = (AnimatorSet) AnimatorInflater.loadAnimator(this,
+                R.anim.tv_pip_controls_fade_in);
+        mPipControlsViewFadeInAnimator.setTarget(mPipControlsView);
+        mPipControlsViewFadeOutAnimator = (AnimatorSet) AnimatorInflater.loadAnimator(this,
+                R.anim.tv_pip_controls_fade_out);
+        mPipControlsViewFadeOutAnimator.setTarget(mPipControlsView);
+
         getWindow().getAttributes().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 
@@ -272,7 +289,6 @@
                 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
         mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent);
 
-        mHasPip = false;
         updatePipUI();
         mPipManager.addListener(mPipListener);
     }
@@ -297,7 +313,7 @@
         RecentsActivityLaunchState launchState = config.getLaunchState();
         boolean wasLaunchedByAm = !launchState.launchedFromHome &&
                 !launchState.launchedFromApp;
-        if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
+        if (wasLaunchedByAm) {
             EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
         }
 
@@ -463,37 +479,25 @@
     }
 
     private void updatePipUI() {
-        if (mHasPip == mPipManager.isPipShown()) {
-            return;
-        }
-        mHasPip = mPipManager.isPipShown();
-        if (mHasPip) {
-            // Place mPipView at the PIP bounds for fine tuned focus handling.
-            Rect pipBounds = mPipManager.getPipBounds();
-            LayoutParams lp = (LayoutParams) mPipView.getLayoutParams();
-            lp.width = pipBounds.width();
-            lp.height = pipBounds.height();
-            lp.leftMargin = pipBounds.left;
-            lp.topMargin = pipBounds.top;
-            mPipView.setLayoutParams(lp);
-
-            mPipView.setVisibility(View.VISIBLE);
-            mPipView.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mPipManager.resizePinnedStack(PipManager.STATE_PIP_MENU);
-                }
-            });
-            mPipView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+        if (mPipManager.isPipShown()) {
+            mPipControlsView.setAlpha(0);
+            mPipControlsView.setVisibility(View.VISIBLE);
+            mPipShadeView.setVisibility(View.INVISIBLE);
+            mPipControlsView.setOnChildFocusChangeListener(new View.OnFocusChangeListener() {
                 @Override
                 public void onFocusChange(View v, boolean hasFocus) {
                     mPipManager.onPipViewFocusChangedInRecents(hasFocus);
+                    if (hasFocus) {
+                        mPipControlsViewFadeInAnimator.start();
+                    } else {
+                        mPipControlsViewFadeOutAnimator.start();
+                    }
                     mPipShadeView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
                 }
             });
             mPipShadeView.setVisibility(View.GONE);
         } else {
-            mPipView.setVisibility(View.GONE);
+            mPipControlsView.setVisibility(View.GONE);
             mPipShadeView.setVisibility(View.GONE);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index 9fd5d55..c1b47dc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -24,10 +24,13 @@
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import com.android.systemui.recents.*;
+
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsActivityLaunchState;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.tv.views.TaskCardView;
@@ -81,8 +84,7 @@
             // If there is no thumbnail transition, but is launching from home into recents, then
             // use a quick home transition and do the animation from home
             if (hasRecentTasks) {
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                ActivityOptions opts = getHomeTransitionActivityOptions(false);
+                ActivityOptions opts = getHomeTransitionActivityOptions();
                 startRecentsActivity(topTask, opts, true /* fromHome */, false /* fromThumbnail */);
             } else {
                 // Otherwise we do the normal fade from an unknown source
@@ -99,12 +101,9 @@
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
         launchState.launchedFromHome = fromHome;
-        launchState.launchedFromSearchHome = false;
         launchState.launchedFromApp = fromThumbnail;
         launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
-        launchState.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
-        launchState.launchedHasConfigurationChanged = false;
 
         Intent intent = new Intent();
         intent.setClassName(RECENTS_PACKAGE, RECENTS_TV_ACTIVITY);
@@ -117,7 +116,6 @@
         } else {
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
-        mCanReuseTaskStackViews = true;
         EventBus.getDefault().send(new RecentsActivityStartingEvent());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
index bf6229c..3d5176f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
@@ -104,28 +104,6 @@
         requestLayout();
     }
 
-    public Task getNextTaskOrTopTask(Task taskToSearch) {
-        Task returnTask = null;
-        boolean found = false;
-        if (mTaskStackHorizontalView != null) {
-            TaskStack stack = mTaskStackHorizontalView.getStack();
-            ArrayList<Task> taskList = stack.getStackTasks();
-            // Iterate the stack views and try and find the focused task
-            for (int j = taskList.size() - 1; j >= 0; --j) {
-                Task task = taskList.get(j);
-                // Return the next task in the line.
-                if (found)
-                    return task;
-                // Remember the first possible task as the top task.
-                if (returnTask == null)
-                    returnTask = task;
-                if (task == taskToSearch)
-                    found = true;
-            }
-        }
-        return returnTask;
-    }
-
     public boolean launchFocusedTask() {
         if (mTaskStackHorizontalView != null) {
             Task task = mTaskStackHorizontalView.getFocusedTask();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
index 5c2de8e..3d0e75a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
@@ -158,7 +158,7 @@
     }
 
     @Override
-    public void onHistoryTaskRemoved(TaskStack stack, Task removedTask, AnimationProps animation) {
-        //No history task on tv
+    public void onStackTasksUpdated(TaskStack stack) {
+        // Do nothing
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 72b914c..035c058 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -46,7 +46,7 @@
     public void reloadOnConfigurationChange(Context context) {
         // This is applied to the edges of each task
         mTaskPadding = context.getResources().getDimensionPixelSize(
-                R.dimen.recents_freeform_workspace_task_padding) / 2;
+                R.dimen.recents_freeform_layout_task_padding) / 2;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index a91bbd4..98616f4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -16,9 +16,15 @@
 
 package com.android.systemui.recents.views;
 
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+
 import android.annotation.Nullable;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityOptions;
+import android.app.ActivityOptions.OnAnimationStartedListener;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -27,10 +33,8 @@
 import android.os.Handler;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
-import android.util.Log;
 import android.view.AppTransitionAnimationSpec;
 import android.view.IAppTransitionAnimationSpecsFuture;
-import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.recents.Recents;
@@ -47,13 +51,9 @@
 import com.android.systemui.recents.model.TaskStack;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
 /**
  * A helper class to create transitions to/from Recents
  */
@@ -82,9 +82,9 @@
         }
     };
 
-    public RecentsTransitionHelper(Context context, Handler handler) {
+    public RecentsTransitionHelper(Context context) {
         mContext = context;
-        mHandler = handler;
+        mHandler = new Handler();
     }
 
     /**
@@ -92,7 +92,7 @@
      */
     public void launchTaskFromRecents(final TaskStack stack, @Nullable final Task task,
             final TaskStackView stackView, final TaskView taskView,
-            final boolean screenPinningRequested, final Rect bounds, int destinationStack) {
+            final boolean screenPinningRequested, final Rect bounds, final int destinationStack) {
         final ActivityOptions opts = ActivityOptions.makeBasic();
         if (bounds != null) {
             opts.setLaunchBounds(bounds.isEmpty() ? null : bounds);
@@ -101,7 +101,12 @@
         final ActivityOptions.OnAnimationStartedListener animStartedListener;
         final IAppTransitionAnimationSpecsFuture transitionFuture;
         if (taskView != null) {
-            transitionFuture = getAppTransitionFuture(task, stackView, destinationStack);
+            transitionFuture = getAppTransitionFuture(new AnimationSpecComposer() {
+                @Override
+                public List<AppTransitionAnimationSpec> composeSpecs() {
+                    return composeAnimationSpecs(task, stackView, destinationStack);
+                }
+            });
             animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
                 @Override
                 public void onAnimationStarted() {
@@ -154,6 +159,23 @@
         }
     }
 
+    public IRemoteCallback wrapStartedListener(final OnAnimationStartedListener listener) {
+        if (listener == null) {
+            return null;
+        }
+        return new IRemoteCallback.Stub() {
+            @Override
+            public void sendResult(Bundle data) throws RemoteException {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        listener.onAnimationStarted();
+                    }
+                });
+            }
+        };
+    }
+
     /**
      * Starts the activity for the launch task.
      *
@@ -181,40 +203,21 @@
         }
 
         if (transitionFuture != null) {
-            IRemoteCallback.Stub callback = null;
-            if (animStartedListener != null) {
-                callback = new IRemoteCallback.Stub() {
-                    @Override
-                    public void sendResult(Bundle data) throws RemoteException {
-                        mHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                if (animStartedListener != null) {
-                                    animStartedListener.onAnimationStarted();
-                                }
-                            }
-                        });
-                    }
-                };
-            }
-            try {
-                synchronized (this) {
-                    mAppTransitionAnimationSpecs = SPECS_WAITING;
-                }
-                WindowManagerGlobal.getWindowManagerService()
-                        .overridePendingAppTransitionMultiThumbFuture(transitionFuture,
-                                callback, true /* scaleUp */);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to override transition: " + e);
-            }
+            ssp.overridePendingAppTransitionMultiThumbFuture(transitionFuture,
+                    wrapStartedListener(animStartedListener), true /* scaleUp */);
         }
     }
 
     /**
      * Creates a future which will later be queried for animation specs for this current transition.
+     *
+     * @param composer The implementation that composes the specs on the UI thread.
      */
-    private IAppTransitionAnimationSpecsFuture getAppTransitionFuture(final Task task,
-            final TaskStackView stackView, final int destinationStack) {
+    public IAppTransitionAnimationSpecsFuture getAppTransitionFuture(
+            final AnimationSpecComposer composer) {
+        synchronized (this) {
+            mAppTransitionAnimationSpecs = SPECS_WAITING;
+        }
         return new IAppTransitionAnimationSpecsFuture.Stub() {
             @Override
             public AppTransitionAnimationSpec[] get() throws RemoteException {
@@ -222,8 +225,7 @@
                     @Override
                     public void run() {
                         synchronized (RecentsTransitionHelper.this) {
-                            mAppTransitionAnimationSpecs = composeAnimationSpecs(task, stackView,
-                                    destinationStack);
+                            mAppTransitionAnimationSpecs = composer.composeSpecs();
                             RecentsTransitionHelper.this.notifyAll();
                         }
                     }
@@ -248,6 +250,17 @@
     }
 
     /**
+     * Composes the transition spec when docking a task, which includes a full task bitmap.
+     */
+    public List<AppTransitionAnimationSpec> composeDockAnimationSpec(
+            TaskView taskView, Rect transform) {
+        TaskViewTransform viewTransform = new TaskViewTransform();
+        viewTransform.fillIn(taskView);
+        return Collections.singletonList(new AppTransitionAnimationSpec(taskView.getTask().key.id,
+                RecentsTransitionHelper.composeTaskBitmap(taskView, viewTransform), transform));
+    }
+
+    /**
      * Composes the animation specs for all the tasks in the target stack.
      */
     private List<AppTransitionAnimationSpec> composeAnimationSpecs(final Task task,
@@ -319,6 +332,43 @@
         return new AppTransitionAnimationSpec(task.key.id, null, taskRect);
     }
 
+    public static Bitmap composeTaskBitmap(TaskView taskView, TaskViewTransform transform) {
+        float scale = transform.scale;
+        int fromWidth = (int) (transform.rect.width() * scale);
+        int fromHeight = (int) (transform.rect.height() * scale);
+        Bitmap b = Bitmap.createBitmap(fromWidth, fromHeight,
+                Bitmap.Config.ARGB_8888);
+
+        if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
+            b.eraseColor(0xFFff0000);
+        } else {
+            Canvas c = new Canvas(b);
+            c.scale(scale, scale);
+            taskView.draw(c);
+            c.setBitmap(null);
+        }
+        return b.createAshmemBitmap();
+    }
+
+    private static Bitmap composeHeaderBitmap(TaskView taskView,
+            TaskViewTransform transform) {
+        float scale = transform.scale;
+        int fromHeaderWidth = (int) (transform.rect.width());
+        int fromHeaderHeight = (int) (taskView.mHeaderView.getMeasuredHeight() * scale);
+        Bitmap b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
+                Bitmap.Config.ARGB_8888);
+
+        if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
+            b.eraseColor(0xFFff0000);
+        } else {
+            Canvas c = new Canvas(b);
+            c.scale(scale, scale);
+            taskView.mHeaderView.draw(c);
+            c.setBitmap(null);
+        }
+        return b.createAshmemBitmap();
+    }
+
     /**
      * Composes a single animation spec for the given {@link TaskView}
      */
@@ -326,21 +376,7 @@
             TaskView taskView, TaskViewTransform transform, boolean addHeaderBitmap) {
         Bitmap b = null;
         if (addHeaderBitmap) {
-            float scale = transform.scale;
-            int fromHeaderWidth = (int) (transform.rect.width());
-            int fromHeaderHeight = (int) (taskView.mHeaderView.getMeasuredHeight() * scale);
-            b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
-                    Bitmap.Config.ARGB_8888);
-
-            if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
-                b.eraseColor(0xFFff0000);
-            } else {
-                Canvas c = new Canvas(b);
-                c.scale(scale, scale);
-                taskView.mHeaderView.draw(c);
-                c.setBitmap(null);
-            }
-            b = b.createAshmemBitmap();
+            b = composeHeaderBitmap(taskView, transform);
         }
 
         Rect taskRect = new Rect();
@@ -351,4 +387,8 @@
         }
         return new AppTransitionAnimationSpec(taskView.getTask().key.id, b, taskRect);
     }
+
+    public interface AnimationSpecComposer {
+        List<AppTransitionAnimationSpec> composeSpecs();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index db97e8f..a1ba493 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -19,8 +19,8 @@
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
+import android.app.ActivityOptions.OnAnimationStartedListener;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -28,9 +28,10 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.Handler;
 import android.util.ArraySet;
 import android.util.AttributeSet;
+import android.view.AppTransitionAnimationSpec;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -48,19 +49,15 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivity;
 import com.android.systemui.recents.RecentsActivityLaunchState;
-import com.android.systemui.recents.RecentsAppWidgetHostView;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.events.activity.ClearHistoryEvent;
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.HideHistoryButtonEvent;
-import com.android.systemui.recents.events.activity.HideHistoryEvent;
+import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskEvent;
-import com.android.systemui.recents.events.activity.ShowHistoryButtonEvent;
-import com.android.systemui.recents.events.activity.ShowHistoryEvent;
-import com.android.systemui.recents.events.activity.ToggleHistoryEvent;
+import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
 import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
 import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
 import com.android.systemui.recents.events.ui.ResetBackgroundScrimEvent;
@@ -68,12 +65,12 @@
 import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.recents.history.RecentsHistoryView;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.RecentsTransitionHelper.AnimationSpecComposer;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 
@@ -90,15 +87,10 @@
     private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
     private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
 
-    private final Handler mHandler;
-
     private TaskStack mStack;
     private TaskStackView mTaskStackView;
-    private RecentsAppWidgetHostView mSearchBar;
-    private TextView mHistoryButton;
-    private TextView mHistoryClearAllButton;
+    private TextView mStackActionButton;
     private TextView mEmptyView;
-    private RecentsHistoryView mHistoryView;
 
     private boolean mAwaitingFirstLayout = true;
     private boolean mLastTaskLaunchedWasFreeform;
@@ -132,27 +124,26 @@
         setWillNotDraw(false);
 
         SystemServicesProxy ssp = Recents.getSystemServices();
-        mHandler = new Handler();
-        mTransitionHelper = new RecentsTransitionHelper(getContext(), mHandler);
+        mTransitionHelper = new RecentsTransitionHelper(getContext());
         mDividerSize = ssp.getDockedDividerSize(context);
         mTouchHandler = new RecentsViewTouchHandler(this);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
 
-        final float cornerRadius = context.getResources().getDimensionPixelSize(
-                R.dimen.recents_task_view_rounded_corners_radius);
         LayoutInflater inflater = LayoutInflater.from(context);
-        if (RecentsDebugFlags.Static.EnableHistory) {
-            mHistoryButton = (TextView) inflater.inflate(R.layout.recents_history_button, this,
-                    false);
-            mHistoryButton.setOnClickListener(new View.OnClickListener() {
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            float cornerRadius = context.getResources().getDimensionPixelSize(
+                    R.dimen.recents_task_view_rounded_corners_radius);
+            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
+                    this, false);
+            mStackActionButton.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
-                    EventBus.getDefault().send(new ToggleHistoryEvent());
+                    // TODO: To be implemented
                 }
             });
-            addView(mHistoryButton);
-            mHistoryButton.setClipToOutline(true);
-            mHistoryButton.setOutlineProvider(new ViewOutlineProvider() {
+            addView(mStackActionButton);
+            mStackActionButton.setClipToOutline(true);
+            mStackActionButton.setOutlineProvider(new ViewOutlineProvider() {
                 @Override
                 public void getOutline(View view, Outline outline) {
                     outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), cornerRadius);
@@ -165,16 +156,17 @@
         setBackground(mBackgroundScrim);
     }
 
-    /** Set/get the bsp root node */
-    public void onResume(boolean isResumingFromVisible, TaskStack stack) {
+    /**
+     * Called from RecentsActivity when it is relaunched.
+     */
+    public void onReload(boolean isResumingFromVisible, boolean isTaskStackEmpty) {
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
 
-        if (mTaskStackView == null || !launchState.launchedReuseTaskStackViews) {
+        if (mTaskStackView == null) {
             isResumingFromVisible = false;
-            removeView(mTaskStackView);
             mTaskStackView = new TaskStackView(getContext());
-            mStack = mTaskStackView.getStack();
+            mTaskStackView.setSystemInsets(mSystemInsets);
             addView(mTaskStackView);
         }
 
@@ -183,9 +175,7 @@
         mLastTaskLaunchedWasFreeform = false;
 
         // Update the stack
-        mTaskStackView.onResume(isResumingFromVisible);
-        mTaskStackView.setTasks(stack, isResumingFromVisible /* notifyStackChanges */,
-                true /* relayoutTaskStack */);
+        mTaskStackView.onReload(isResumingFromVisible);
 
         if (isResumingFromVisible) {
             // If we are already visible, then restore the background scrim
@@ -195,12 +185,20 @@
             // Otherwise, defer until the enter animation completes to animate the scrim alpha with
             // the tasks for the home animation.
             if (launchState.launchedWhileDocking || launchState.launchedFromApp
-                    || mStack.getTaskCount() == 0) {
+                    || isTaskStackEmpty) {
                 mBackgroundScrim.setAlpha((int) (DEFAULT_SCRIM_ALPHA * 255));
             } else {
                 mBackgroundScrim.setAlpha(0);
             }
         }
+    }
+
+    /**
+     * Called from RecentsActivity when the task stack is updated.
+     */
+    public void updateStack(TaskStack stack) {
+        mStack = stack;
+        mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
 
         // Update the top level view's visibilities
         if (stack.getTaskCount() > 0) {
@@ -211,49 +209,19 @@
     }
 
     /**
+     * Returns the current TaskStack.
+     */
+    public TaskStack getStack() {
+        return mStack;
+    }
+
+    /**
      * Returns whether the last task launched was in the freeform stack or not.
      */
     public boolean isLastTaskLaunchedFreeform() {
         return mLastTaskLaunchedWasFreeform;
     }
 
-    /**
-     * Returns whether the history is visible or not.
-     */
-    public boolean isHistoryVisible() {
-        return mHistoryView != null && mHistoryView.isVisible();
-    }
-
-    /**
-     * Returns the currently set task stack.
-     */
-    public TaskStack getTaskStack() {
-        return mStack;
-    }
-
-    /** Gets the next task in the stack - or if the last - the top task */
-    public Task getNextTaskOrTopTask(Task taskToSearch) {
-        Task returnTask = null;
-        boolean found = false;
-        if (mTaskStackView != null) {
-            TaskStack stack = mTaskStackView.getStack();
-            ArrayList<Task> taskList = stack.getStackTasks();
-            // Iterate the stack views and try and find the focused task
-            for (int j = taskList.size() - 1; j >= 0; --j) {
-                Task task = taskList.get(j);
-                // Return the next task in the line.
-                if (found)
-                    return task;
-                // Remember the first possible task as the top task.
-                if (returnTask == null)
-                    returnTask = task;
-                if (task == taskToSearch)
-                    found = true;
-            }
-        }
-        return returnTask;
-    }
-
     /** Launches the focused task from the first stack if possible */
     public boolean launchFocusedTask(int logEvent) {
         if (mTaskStackView != null) {
@@ -306,37 +274,16 @@
         return false;
     }
 
-    /** Adds the search bar */
-    public void setSearchBar(RecentsAppWidgetHostView searchBar) {
-        // Remove the previous search bar if one exists
-        if (mSearchBar != null && indexOfChild(mSearchBar) > -1) {
-            removeView(mSearchBar);
-        }
-        // Add the new search bar
-        if (searchBar != null) {
-            mSearchBar = searchBar;
-            addView(mSearchBar);
-        }
-    }
-
-    /** Returns whether there is currently a search bar */
-    public boolean hasValidSearchBar() {
-        return mSearchBar != null && !mSearchBar.isReinflateRequired();
-    }
-
     /**
      * Hides the task stack and shows the empty view.
      */
     public void showEmptyView(int msgResId) {
-        if (RecentsDebugFlags.Static.EnableSearchBar && (mSearchBar != null)) {
-            mSearchBar.setVisibility(View.INVISIBLE);
-        }
         mTaskStackView.setVisibility(View.INVISIBLE);
         mEmptyView.setText(msgResId);
         mEmptyView.setVisibility(View.VISIBLE);
         mEmptyView.bringToFront();
-        if (RecentsDebugFlags.Static.EnableHistory) {
-            mHistoryButton.bringToFront();
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            mStackActionButton.bringToFront();
         }
     }
 
@@ -346,15 +293,9 @@
     public void hideEmptyView() {
         mEmptyView.setVisibility(View.INVISIBLE);
         mTaskStackView.setVisibility(View.VISIBLE);
-        if (RecentsDebugFlags.Static.EnableSearchBar && (mSearchBar != null)) {
-            mSearchBar.setVisibility(View.VISIBLE);
-        }
         mTaskStackView.bringToFront();
-        if (mSearchBar != null) {
-            mSearchBar.bringToFront();
-        }
-        if (RecentsDebugFlags.Static.EnableHistory) {
-            mHistoryButton.bringToFront();
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            mStackActionButton.bringToFront();
         }
     }
 
@@ -377,25 +318,10 @@
      */
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        RecentsConfiguration config = Recents.getConfiguration();
         int width = MeasureSpec.getSize(widthMeasureSpec);
         int height = MeasureSpec.getSize(heightMeasureSpec);
 
-        // Get the search bar bounds and measure the search bar layout
-        Rect searchBarSpaceBounds = new Rect();
-        if (mSearchBar != null) {
-            config.getSearchBarBounds(new Rect(0, 0, width, height), mSystemInsets.top,
-                    searchBarSpaceBounds);
-            mSearchBar.measure(
-                    MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.width(), MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.height(), MeasureSpec.EXACTLY));
-        }
-
-        Rect taskStackBounds = new Rect();
-        config.getTaskStackBounds(new Rect(0, 0, width, height), mSystemInsets.top,
-                mSystemInsets.right, searchBarSpaceBounds, taskStackBounds);
-        if (mTaskStackView != null && mTaskStackView.getVisibility() != GONE) {
-            mTaskStackView.setTaskStackBounds(taskStackBounds, mSystemInsets);
+        if (mTaskStackView.getVisibility() != GONE) {
             mTaskStackView.measure(widthMeasureSpec, heightMeasureSpec);
         }
 
@@ -405,23 +331,12 @@
                     MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
         }
 
-        if (RecentsDebugFlags.Static.EnableHistory) {
-            // Measure the history view
-            if (mHistoryView != null && mHistoryView.getVisibility() != GONE) {
-                measureChild(mHistoryView, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
-            }
-
-            // Measure the history button within the constraints of the space above the stack
-            Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
-            measureChild(mHistoryButton,
-                    MeasureSpec.makeMeasureSpec(historyButtonRect.width(), MeasureSpec.AT_MOST),
-                    MeasureSpec.makeMeasureSpec(historyButtonRect.height(), MeasureSpec.AT_MOST));
-            if (mHistoryClearAllButton != null && mHistoryClearAllButton.getVisibility() != GONE) {
-                measureChild(mHistoryClearAllButton,
-                    MeasureSpec.makeMeasureSpec(historyButtonRect.width(), MeasureSpec.AT_MOST),
-                    MeasureSpec.makeMeasureSpec(historyButtonRect.height(), MeasureSpec.AT_MOST));
-            }
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            // Measure the stack action button within the constraints of the space above the stack
+            Rect actionButtonRect = mTaskStackView.mLayoutAlgorithm.mStackActionButtonRect;
+            measureChild(mStackActionButton,
+                    MeasureSpec.makeMeasureSpec(actionButtonRect.width(), MeasureSpec.AT_MOST),
+                    MeasureSpec.makeMeasureSpec(actionButtonRect.height(), MeasureSpec.AT_MOST));
         }
 
         setMeasuredDimension(width, height);
@@ -432,19 +347,7 @@
      */
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        RecentsConfiguration config = Recents.getConfiguration();
-
-        // Get the search bar bounds so that we lay it out
-        Rect measuredRect = new Rect(0, 0, getMeasuredWidth(), getMeasuredHeight());
-        Rect searchBarSpaceBounds = new Rect();
-        if (mSearchBar != null) {
-            config.getSearchBarBounds(measuredRect,
-                    mSystemInsets.top, searchBarSpaceBounds);
-            mSearchBar.layout(searchBarSpaceBounds.left, searchBarSpaceBounds.top,
-                    searchBarSpaceBounds.right, searchBarSpaceBounds.bottom);
-        }
-
-        if (mTaskStackView != null && mTaskStackView.getVisibility() != GONE) {
+        if (mTaskStackView.getVisibility() != GONE) {
             mTaskStackView.layout(left, top, left + getMeasuredWidth(), top + getMeasuredHeight());
         }
 
@@ -459,39 +362,19 @@
             mEmptyView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
         }
 
-        if (RecentsDebugFlags.Static.EnableHistory) {
-            // Layout the history view
-            if (mHistoryView != null && mHistoryView.getVisibility() != GONE) {
-                mHistoryView.layout(left, top, right, bottom);
-            }
-
-            // Layout the history button such that its drawable is start-aligned with the stack,
-            // vertically centered in the available space above the stack
-            Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
-            int historyLeft = isLayoutRtl()
-                    ? historyButtonRect.right + mHistoryButton.getPaddingStart()
-                    - mHistoryButton.getMeasuredWidth()
-                    : historyButtonRect.left - mHistoryButton.getPaddingStart();
-            int historyTop = historyButtonRect.top +
-                    (historyButtonRect.height() - mHistoryButton.getMeasuredHeight()) / 2;
-            mHistoryButton.layout(historyLeft, historyTop,
-                    historyLeft + mHistoryButton.getMeasuredWidth(),
-                    historyTop + mHistoryButton.getMeasuredHeight());
-
-            // Layout the history clear all button such that it is end-aligned with the stack,
-            // vertically centered in the available space above the stack
-            if (mHistoryClearAllButton != null && mHistoryClearAllButton.getVisibility() != GONE) {
-                int clearAllLeft = isLayoutRtl()
-                        ? historyButtonRect.left - mHistoryClearAllButton.getPaddingStart()
-                        : historyButtonRect.right + mHistoryClearAllButton.getPaddingStart()
-                        - mHistoryClearAllButton.getMeasuredWidth();
-                int clearAllTop = historyButtonRect.top +
-                        (historyButtonRect.height() - mHistoryClearAllButton.getMeasuredHeight()) /
-                                2;
-                mHistoryClearAllButton.layout(clearAllLeft, clearAllTop,
-                        clearAllLeft + mHistoryClearAllButton.getMeasuredWidth(),
-                        clearAllTop + mHistoryClearAllButton.getMeasuredHeight());
-            }
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            // Layout the stack action button such that its drawable is start-aligned with the
+            // stack, vertically centered in the available space above the stack
+            Rect actionButtonRect = mTaskStackView.mLayoutAlgorithm.mStackActionButtonRect;
+            int buttonLeft = isLayoutRtl()
+                    ? actionButtonRect.right + mStackActionButton.getPaddingStart()
+                    - mStackActionButton.getMeasuredWidth()
+                    : actionButtonRect.left - mStackActionButton.getPaddingStart();
+            int buttonTop = actionButtonRect.top +
+                    (actionButtonRect.height() - mStackActionButton.getMeasuredHeight()) / 2;
+            mStackActionButton.layout(buttonLeft, buttonTop,
+                    buttonLeft + mStackActionButton.getMeasuredWidth(),
+                    buttonTop + mStackActionButton.getMeasuredHeight());
         }
 
         if (mAwaitingFirstLayout) {
@@ -511,6 +394,7 @@
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         mSystemInsets.set(insets.getSystemWindowInsets());
+        mTaskStackView.setSystemInsets(mSystemInsets);
         requestLayout();
         return insets;
     }
@@ -560,9 +444,9 @@
 
     public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
         int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION;
-        if (RecentsDebugFlags.Static.EnableHistory) {
-            // Hide the history button
-            hideHistoryButton(taskViewExitToHomeDuration, false /* translate */);
+        if (RecentsDebugFlags.Static.EnableStackActionButton) {
+            // Hide the stack action button
+            hideStackActionButton(taskViewExitToHomeDuration, false /* translate */);
         }
         animateBackgroundScrim(0f, taskViewExitToHomeDuration);
     }
@@ -611,31 +495,30 @@
             event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
                     taskViewRect.right, taskViewRect.bottom);
 
-            // Remove the task view after it is docked
-            mTaskStackView.updateLayoutAlgorithm(false /* boundScroll */);
-            stackLayout.getStackTransform(event.task, stackScroller.getStackScroll(), tmpTransform,
-                    null);
-            tmpTransform.alpha = 0;
-            tmpTransform.scale = 1f;
-            tmpTransform.rect.set(taskViewRect);
-            mTaskStackView.updateTaskViewToTransform(event.taskView, tmpTransform,
-                    new AnimationProps(125, Interpolators.ALPHA_OUT,
-                            new AnimatorListenerAdapter() {
-                                @Override
-                                public void onAnimationEnd(Animator animation) {
-                                    // Dock the task and launch it
-                                    SystemServicesProxy ssp = Recents.getSystemServices();
-                                    ssp.startTaskInDockedMode(getContext(), event.taskView,
-                                            event.task.key.id, dockState.createMode);
+            final OnAnimationStartedListener startedListener = new OnAnimationStartedListener() {
+                @Override
+                public void onAnimationStarted() {
+                    EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
+                    mTaskStackView.getStack().removeTask(event.task, AnimationProps.IMMEDIATE,
+                            true /* fromDockGesture */);
+                }
+            };
 
-                                    // Animate the stack accordingly
-                                    AnimationProps stackAnim = new AnimationProps(
-                                            TaskStackView.DEFAULT_SYNC_STACK_DURATION,
-                                            Interpolators.FAST_OUT_SLOW_IN);
-                                    mTaskStackView.getStack().removeTask(event.task, stackAnim,
-                                            true /* fromDockGesture */);
-                                }
-                            }));
+            // Dock the task and launch it
+            SystemServicesProxy ssp = Recents.getSystemServices();
+            ssp.startTaskInDockedMode(event.task.key.id, dockState.createMode);
+            final Rect taskRect = getTaskRect(event.taskView);
+            IAppTransitionAnimationSpecsFuture future = mTransitionHelper.getAppTransitionFuture(
+                    new AnimationSpecComposer() {
+                        @Override
+                        public List<AppTransitionAnimationSpec> composeSpecs() {
+                            return mTransitionHelper.composeDockAnimationSpec(
+                                    event.taskView, taskRect);
+                        }
+                    });
+            ssp.overridePendingAppTransitionMultiThumbFuture(future,
+                    mTransitionHelper.wrapStartedListener(startedListener),
+                    true /* scaleUp */);
 
             MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP);
         } else {
@@ -645,6 +528,15 @@
         }
     }
 
+    private Rect getTaskRect(TaskView taskView) {
+        int[] location = taskView.getLocationOnScreen();
+        int viewX = location[0];
+        int viewY = location[1];
+        return new Rect(viewX, viewY,
+                (int) (viewX + taskView.getWidth() * taskView.getScaleX()),
+                (int) (viewY + taskView.getHeight() * taskView.getScaleY()));
+    }
+
     public final void onBusEvent(DraggingInRecentsEvent event) {
         if (mTaskStackView.getTaskViews().size() > 0) {
             setTranslationY(event.distanceFromTop - mTaskStackView.getTaskViews().get(0).getY());
@@ -687,144 +579,47 @@
         animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, DEFAULT_UPDATE_SCRIM_DURATION);
     }
 
-    public final void onBusEvent(ToggleHistoryEvent event) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
+    public final void onBusEvent(ShowStackActionButtonEvent event) {
+        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
             return;
         }
 
-        if (mHistoryView != null && mHistoryView.isVisible()) {
-            EventBus.getDefault().send(new HideHistoryEvent(true /* animate */));
-        } else {
-            EventBus.getDefault().send(new ShowHistoryEvent());
-        }
+        showStackActionButton(150, event.translate);
     }
 
-    public final void onBusEvent(ShowHistoryEvent event) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
+    public final void onBusEvent(HideStackActionButtonEvent event) {
+        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
             return;
         }
 
-        if (mHistoryView == null) {
-            LayoutInflater inflater = LayoutInflater.from(getContext());
-            mHistoryView = (RecentsHistoryView) inflater.inflate(R.layout.recents_history, this,
-                    false);
-            addView(mHistoryView);
-
-            final float cornerRadius = getResources().getDimensionPixelSize(
-                    R.dimen.recents_task_view_rounded_corners_radius);
-            mHistoryClearAllButton = (TextView) inflater.inflate(
-                    R.layout.recents_history_clear_all_button, this, false);
-            mHistoryClearAllButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    EventBus.getDefault().send(new ClearHistoryEvent());
-                }
-            });
-            mHistoryClearAllButton.setClipToOutline(true);
-            mHistoryClearAllButton.setOutlineProvider(new ViewOutlineProvider() {
-                @Override
-                public void getOutline(View view, Outline outline) {
-                    outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), cornerRadius);
-                }
-            });
-            addView(mHistoryClearAllButton);
-
-            // Since this history view is inflated by a view stub after the insets have already
-            // been applied, we have to set them ourselves initial from the insets that were last
-            // provided.
-            mHistoryView.setSystemInsets(mSystemInsets);
-            mHistoryView.setHeaderHeight(mHistoryButton.getMeasuredHeight());
-            mHistoryButton.bringToFront();
-            mHistoryClearAllButton.bringToFront();
-        }
-
-        // Animate the empty view in parallel with the history view (the task view animations are
-        // handled in TaskStackView)
-        Rect stackRect = mTaskStackView.mLayoutAlgorithm.mStackRect;
-        if (mEmptyView.getVisibility() == View.VISIBLE) {
-            int historyTransitionDuration = getResources().getInteger(
-                    R.integer.recents_history_transition_duration);
-            mEmptyView.animate()
-                    .alpha(0f)
-                    .translationY(stackRect.height() / 2)
-                    .setDuration(historyTransitionDuration)
-                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                    .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            mEmptyView.setVisibility(View.INVISIBLE);
-                        }
-                    })
-                    .start();
-        }
-
-        mHistoryView.show(mStack, stackRect.height(), mHistoryClearAllButton);
-    }
-
-    public final void onBusEvent(HideHistoryEvent event) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
-            return;
-        }
-
-        // Animate the empty view in parallel with the history view (the task view animations are
-        // handled in TaskStackView)
-        Rect stackRect = mTaskStackView.mLayoutAlgorithm.mStackRect;
-        if (mStack.getTaskCount() == 0) {
-            int historyTransitionDuration = getResources().getInteger(
-                    R.integer.recents_history_transition_duration);
-            mEmptyView.setVisibility(View.VISIBLE);
-            mEmptyView.animate()
-                    .alpha(1f)
-                    .translationY(0)
-                    .setDuration(historyTransitionDuration)
-                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                    .start();
-        }
-
-        mHistoryView.hide(event.animate, stackRect.height(), mHistoryClearAllButton);
-    }
-
-    public final void onBusEvent(ShowHistoryButtonEvent event) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
-            return;
-        }
-
-        showHistoryButton(150, event.translate);
-    }
-
-    public final void onBusEvent(HideHistoryButtonEvent event) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
-            return;
-        }
-
-        hideHistoryButton(100, true /* translate */);
+        hideStackActionButton(100, true /* translate */);
     }
 
     /**
-     * Shows the history button.
+     * Shows the stack action button.
      */
-    private void showHistoryButton(final int duration, final boolean translate) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
+    private void showStackActionButton(final int duration, final boolean translate) {
+        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
             return;
         }
 
         final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
-        if (mHistoryButton.getVisibility() == View.INVISIBLE) {
-            mHistoryButton.setVisibility(View.VISIBLE);
-            mHistoryButton.setAlpha(0f);
+        if (mStackActionButton.getVisibility() == View.INVISIBLE) {
+            mStackActionButton.setVisibility(View.VISIBLE);
+            mStackActionButton.setAlpha(0f);
             if (translate) {
-                mHistoryButton.setTranslationY(-mHistoryButton.getMeasuredHeight() * 0.25f);
+                mStackActionButton.setTranslationY(-mStackActionButton.getMeasuredHeight() * 0.25f);
             } else {
-                mHistoryButton.setTranslationY(0f);
+                mStackActionButton.setTranslationY(0f);
             }
             postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
                 @Override
                 public void run() {
                     if (translate) {
-                        mHistoryButton.animate()
+                        mStackActionButton.animate()
                             .translationY(0f);
                     }
-                    mHistoryButton.animate()
+                    mStackActionButton.animate()
                             .alpha(1f)
                             .setDuration(duration)
                             .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
@@ -837,40 +632,40 @@
     }
 
     /**
-     * Hides the history button.
+     * Hides the stack action button.
      */
-    private void hideHistoryButton(int duration, boolean translate) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
+    private void hideStackActionButton(int duration, boolean translate) {
+        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
             return;
         }
 
         final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
-        hideHistoryButton(duration, translate, postAnimationTrigger);
+        hideStackActionButton(duration, translate, postAnimationTrigger);
         postAnimationTrigger.flushLastDecrementRunnables();
     }
 
     /**
-     * Hides the history button.
+     * Hides the stack action button.
      */
-    private void hideHistoryButton(int duration, boolean translate,
-            final ReferenceCountedTrigger postAnimationTrigger) {
-        if (!RecentsDebugFlags.Static.EnableHistory) {
+    private void hideStackActionButton(int duration, boolean translate,
+                                       final ReferenceCountedTrigger postAnimationTrigger) {
+        if (!RecentsDebugFlags.Static.EnableStackActionButton) {
             return;
         }
 
-        if (mHistoryButton.getVisibility() == View.VISIBLE) {
+        if (mStackActionButton.getVisibility() == View.VISIBLE) {
             if (translate) {
-                mHistoryButton.animate()
-                    .translationY(-mHistoryButton.getMeasuredHeight() * 0.25f);
+                mStackActionButton.animate()
+                    .translationY(-mStackActionButton.getMeasuredHeight() * 0.25f);
             }
-            mHistoryButton.animate()
+            mStackActionButton.animate()
                     .alpha(0f)
                     .setDuration(duration)
                     .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                     .withEndAction(new Runnable() {
                         @Override
                         public void run() {
-                            mHistoryButton.setVisibility(View.INVISIBLE);
+                            mStackActionButton.setVisibility(View.INVISIBLE);
                             postAnimationTrigger.decrement();
                         }
                     })
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
index 19b219a..9c8189a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -16,11 +16,9 @@
 
 package com.android.systemui.recents.views;
 
-import android.animation.AnimatorListenerAdapter;
 import android.app.Activity;
 import android.content.Context;
 import android.view.View;
-import android.view.ViewPropertyAnimator;
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -48,7 +46,7 @@
 
     /**
      * Prepares the scrim views for animating when entering Recents. This will be called before
-     * the first draw.
+     * the first draw, unless we are updating the scrim on configuration change.
      */
     public void prepareEnterRecentsAnimation(boolean hasNavBarScrim, boolean animateNavBarScrim) {
         mHasNavBarScrim = hasNavBarScrim;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index b36d5d1..1c7d609 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -65,6 +65,12 @@
          */
         void onStartLaunchTargetLaunchAnimation(int duration, boolean screenPinningRequested,
                 ReferenceCountedTrigger postAnimationTrigger);
+
+        /**
+         * Callback to start the animation for the front {@link TaskView} if there is no launch
+         * target.
+         */
+        void onStartFrontTaskEnterAnimation(boolean screenPinningEnabled);
     }
 
     private static final int FRAME_OFFSET_MS = 16;
@@ -126,9 +132,9 @@
 
         int offscreenYOffset = stackLayout.mStackRect.height();
         int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize(
-                R.dimen.recents_task_view_affiliate_group_enter_offset);
+                R.dimen.recents_task_stack_animation_affiliate_enter_offset);
         int launchedWhileDockingOffset = res.getDimensionPixelSize(
-                R.dimen.recents_task_view_launched_while_docking_offset);
+                R.dimen.recents_task_stack_animation_launched_while_docking_offset);
 
         // Prepare each of the task views for their enter animation from front to back
         List<TaskView> taskViews = mStackView.getTaskViews();
@@ -146,8 +152,6 @@
 
             if (hideTask) {
                 tv.setVisibility(View.INVISIBLE);
-            } else if (launchState.launchedHasConfigurationChanged) {
-                // Just load the views as-is
             } else if (launchState.launchedFromApp && !launchState.launchedWhileDocking) {
                 if (task.isLaunchTarget) {
                     tv.onPrepareLaunchTargetForEnterAnimation();
@@ -164,6 +168,7 @@
                 // Move the task view off screen (below) so we can animate it in
                 RectF bounds = new RectF(mTmpTransform.rect);
                 bounds.offset(0, offscreenYOffset);
+                tv.setAlpha(0f);
                 tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right,
                         (int) bounds.bottom);
             } else if (launchState.launchedWhileDocking) {
@@ -232,7 +237,7 @@
                                     @Override
                                     public void onAnimationEnd(Animator animation) {
                                         postAnimationTrigger.decrement();
-                                        tv.setClipViewInStack(false);
+                                        tv.setClipViewInStack(true);
                                     }
                                 });
                         postAnimationTrigger.increment();
@@ -254,6 +259,9 @@
                         .setListener(postAnimationTrigger.decrementOnAnimationEnd());
                 postAnimationTrigger.increment();
                 mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
+                if (i == taskViewCount - 1) {
+                    tv.onStartFrontTaskEnterAnimation(mStackView.mScreenPinningEnabled);
+                }
             } else if (launchState.launchedWhileDocking) {
                 // Animate the tasks up
                 AnimationProps taskAnimation = new AnimationProps()
@@ -312,6 +320,7 @@
 
             stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
                     null);
+            mTmpTransform.alpha = 0f;
             mTmpTransform.rect.offset(0, offscreenYOffset);
             mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
         }
@@ -330,7 +339,7 @@
         int taskViewExitToAppDuration = res.getInteger(
                 R.integer.recents_task_exit_to_app_duration);
         int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize(
-                R.dimen.recents_task_view_affiliate_group_enter_offset);
+                R.dimen.recents_task_stack_animation_affiliate_enter_offset);
 
         Task launchingTask = launchingTaskView.getTask();
         List<TaskView> taskViews = mStackView.getTaskViews();
@@ -343,6 +352,12 @@
 
             if (tv == launchingTaskView) {
                 tv.setClipViewInStack(false);
+                postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
+                    @Override
+                    public void run() {
+                        tv.setClipViewInStack(true);
+                    }
+                });
                 tv.onStartLaunchTargetLaunchAnimation(taskViewExitToAppDuration,
                         screenPinningRequested, postAnimationTrigger);
             } else if (currentTaskOccludesLaunchTarget) {
@@ -375,7 +390,8 @@
         int taskViewRemoveAnimTranslationXPx = res.getDimensionPixelSize(
                 R.dimen.recents_task_view_remove_anim_translation_x);
 
-        // Disabling clipping with the stack while the view is animating away
+        // Disabling clipping with the stack while the view is animating away, this will get
+        // restored when the task is next picked up from the view pool
         deleteTaskView.setClipViewInStack(false);
 
         // Compose the new animation and transform and star the animation
@@ -384,9 +400,6 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 postAnimationTrigger.decrement();
-
-                // Re-enable clipping with the stack (we will reuse this view)
-                deleteTaskView.setClipViewInStack(true);
             }
         });
         postAnimationTrigger.increment();
@@ -399,62 +412,6 @@
     }
 
     /**
-     * Starts the animation to hide the {@link TaskView}s when the history is shown.
-     */
-    public void startShowHistoryAnimation(ReferenceCountedTrigger postAnimationTrigger) {
-        Resources res = mStackView.getResources();
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-        TaskStackViewScroller stackScroller = mStackView.getScroller();
-
-        int offscreenY = stackLayout.mStackRect.bottom;
-        int historyTransitionDuration = res.getInteger(
-                R.integer.recents_history_transition_duration);
-        int startDelayIncr = 16;
-
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = taskViewCount - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
-            Task task = tv.getTask();
-            AnimationProps taskAnimation = new AnimationProps(startDelayIncr * i,
-                    historyTransitionDuration, Interpolators.FAST_OUT_SLOW_IN,
-                    postAnimationTrigger.decrementOnAnimationEnd());
-            postAnimationTrigger.increment();
-
-            stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
-                    null);
-            mTmpTransform.alpha = 0f;
-            mTmpTransform.rect.offsetTo(mTmpTransform.rect.left, offscreenY);
-            mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
-        }
-    }
-
-    /**
-     * Starts the animation to show the {@link TaskView}s when the history is hidden.
-     */
-    public void startHideHistoryAnimation() {
-        Resources res = mStackView.getResources();
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
-        TaskStackViewScroller stackScroller = mStackView.getScroller();
-
-        int historyTransitionDuration = res.getInteger(
-                R.integer.recents_history_transition_duration);
-        int startDelayIncr = 16;
-
-        List<TaskView> taskViews = mStackView.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = taskViewCount - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
-            AnimationProps taskAnimation = new AnimationProps(startDelayIncr * i,
-                    historyTransitionDuration, Interpolators.FAST_OUT_SLOW_IN);
-            stackLayout.getStackTransform(tv.getTask(), stackScroller.getStackScroll(),
-                    mTmpTransform, null);
-            mTmpTransform.alpha = 1f;
-            mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
-        }
-    }
-
-    /**
      * Starts the animation to focus the next {@link TaskView} when paging through recents.
      *
      * @return whether or not this will trigger a scroll in the stack
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 6df5884..8a1727a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -16,7 +16,9 @@
 
 package com.android.systemui.recents.views;
 
+import android.annotation.IntDef;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Path;
 import android.graphics.Rect;
@@ -36,6 +38,8 @@
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -97,8 +101,10 @@
 }
 
 /**
- * The layout logic for a TaskStackView.  This layout can have two states focused and unfocused,
- * and in the focused state, there is a task that is displayed more prominently in the stack.
+ * The layout logic for a TaskStackView.  This layout needs to be able to calculate the stack layout
+ * without an activity-specific context only with the information passed in.  This layout can have
+ * two states focused and unfocused, and in the focused state, there is a task that is displayed
+ * more prominently in the stack.
  */
 public class TaskStackLayoutAlgorithm {
 
@@ -107,13 +113,28 @@
     public static final float OUTLINE_ALPHA_MIN_VALUE = 0f;
     public static final float OUTLINE_ALPHA_MAX_VALUE = 2f;
 
-    // The maximum dim on the tasks
+    // The medium/maximum dim on the tasks
+    private static final float MED_DIM = 0.15f;
     private static final float MAX_DIM = 0.25f;
 
     // The various focus states
     public static final int STATE_FOCUSED = 1;
     public static final int STATE_UNFOCUSED = 0;
 
+    // The side that an offset is anchored
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({FROM_TOP, FROM_BOTTOM})
+    public @interface AnchorSide {}
+    private static final int FROM_TOP = 0;
+    private static final int FROM_BOTTOM = 1;
+
+    // The extent that we care about when calculating fractions
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({WIDTH, HEIGHT})
+    public @interface Extent {}
+    private static final int WIDTH = 0;
+    private static final int HEIGHT = 1;
+
     public interface TaskStackLayoutAlgorithmCallbacks {
         void onFocusStateChanged(int prevFocusState, int curFocusState);
     }
@@ -165,22 +186,24 @@
          * @param taskStackBounds the full rect that the freeform rect can take up
          */
         public void computeRects(Rect freeformRectOut, Rect stackRectOut,
-                Rect taskStackBounds, int widthPadding, int heightPadding, int stackBottomOffset) {
-            int availableHeight = taskStackBounds.height() - stackBottomOffset;
+                Rect taskStackBounds, int topMargin, int freeformGap, int stackBottomOffset) {
+            // The freeform height is the visible height (not including system insets) - padding
+            // above freeform and below stack - gap between the freeform and stack
+            int availableHeight = taskStackBounds.height() - topMargin - stackBottomOffset;
             int ffPaddedHeight = (int) (availableHeight * freeformHeightPct);
-            int ffHeight = Math.max(0, ffPaddedHeight - (2 * heightPadding));
-            freeformRectOut.set(taskStackBounds.left + widthPadding,
-                    taskStackBounds.top + heightPadding,
-                    taskStackBounds.right - widthPadding,
-                    taskStackBounds.top + heightPadding + ffHeight);
-            stackRectOut.set(taskStackBounds.left + widthPadding,
+            int ffHeight = Math.max(0, ffPaddedHeight - freeformGap);
+            freeformRectOut.set(taskStackBounds.left,
+                    taskStackBounds.top + topMargin,
+                    taskStackBounds.right,
+                    taskStackBounds.top + topMargin + ffHeight);
+            stackRectOut.set(taskStackBounds.left,
                     taskStackBounds.top,
-                    taskStackBounds.right - widthPadding,
+                    taskStackBounds.right,
                     taskStackBounds.bottom);
             if (ffPaddedHeight > 0) {
                 stackRectOut.top += ffPaddedHeight;
             } else {
-                stackRectOut.top += heightPadding;
+                stackRectOut.top += topMargin;
             }
         }
     }
@@ -204,44 +227,53 @@
     // The task bounds (untransformed) for layout.  This rect is anchored at mTaskRoot.
     @ViewDebug.ExportedProperty(category="recents")
     public Rect mTaskRect = new Rect();
-    // The freeform workspace bounds, inset from the top by the search bar, and is a fixed height
+    // The freeform workspace bounds, inset by the top system insets and is a fixed height
     @ViewDebug.ExportedProperty(category="recents")
     public Rect mFreeformRect = new Rect();
-    // The stack bounds, inset from the top by the search bar, and runs to
-    // the bottom of the screen
+    // The stack bounds, inset from the top system insets, and runs to the bottom of the screen
     @ViewDebug.ExportedProperty(category="recents")
     public Rect mStackRect = new Rect();
     // This is the current system insets
     @ViewDebug.ExportedProperty(category="recents")
     public Rect mSystemInsets = new Rect();
-    // This is the bounds of the history button above the stack rect
+    // This is the bounds of the stack action above the stack rect
     @ViewDebug.ExportedProperty(category="recents")
-    public Rect mHistoryButtonRect = new Rect();
+    public Rect mStackActionButtonRect = new Rect();
 
     // The visible ranges when the stack is focused and unfocused
     private Range mUnfocusedRange;
     private Range mFocusedRange;
 
-    // The initial offset from the top and bottom of the stack
+    // The base top margin for the stack from the system insets
     @ViewDebug.ExportedProperty(category="recents")
-    private int mInitialTopPeekHeight;
+    private int mBaseTopMargin;
+    // The base side margin for the stack from the system insets
     @ViewDebug.ExportedProperty(category="recents")
-    private int mInitialBottomPeekHeight;
+    private int mBaseSideMargin;
+    // The base bottom margin for the stack from the system insets
+    @ViewDebug.ExportedProperty(category="recents")
+    private int mBaseBottomMargin;
+    private int mMinMargin;
 
-    // The offset from the top when scrolled to the top of the stack
+    // The gap between the freeform and stack layouts
+    @ViewDebug.ExportedProperty(category="recents")
+    private int mFreeformStackGap;
+
+    // The initial offset that the focused task is from the top
+    @ViewDebug.ExportedProperty(category="recents")
+    private int mInitialTopOffset;
+    private int mBaseInitialTopOffset;
+    // The initial offset that the launch-from task is from the bottom
+    @ViewDebug.ExportedProperty(category="recents")
+    private int mInitialBottomOffset;
+    private int mBaseInitialBottomOffset;
+
+    // The height between the top margin and the top of the focused task
     @ViewDebug.ExportedProperty(category="recents")
     private int mFocusedTopPeekHeight;
+    // The height between the bottom margin and the top of task in front of the focused task
     @ViewDebug.ExportedProperty(category="recents")
-    private int mFocusedBottomTaskPeekHeight;
-
-    // The offset from the top of the stack to the top of the bounds when the stack is scrolled to
-    // the end
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mStackTopOffset;
-
-    // The height of the header bar
-    @ViewDebug.ExportedProperty(category="recents")
-    private int mHeaderBarHeight;
+    private int mFocusedBottomPeekHeight;
 
     // The offset from the bottom of the stack to the bottom of the bounds when the stack is
     // scrolled to the front
@@ -307,9 +339,23 @@
     TaskViewTransform mFrontOfStackTransform = new TaskViewTransform();
 
     public TaskStackLayoutAlgorithm(Context context, TaskStackLayoutAlgorithmCallbacks cb) {
+        Resources res = context.getResources();
         mContext = context;
         mCb = cb;
         mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
+        mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
+        mBaseTopMargin = getDimensionForDevice(res,
+                R.dimen.recents_layout_top_margin_phone,
+                R.dimen.recents_layout_top_margin_tablet,
+                R.dimen.recents_layout_top_margin_tablet_xlarge);
+        mBaseSideMargin = getDimensionForDevice(res,
+                R.dimen.recents_layout_side_margin_phone,
+                R.dimen.recents_layout_side_margin_tablet,
+                R.dimen.recents_layout_side_margin_tablet_xlarge);
+        mBaseBottomMargin = res.getDimensionPixelSize(R.dimen.recents_layout_bottom_margin);
+        mFreeformStackGap =
+                res.getDimensionPixelSize(R.dimen.recents_freeform_layout_bottom_margin);
+
         reloadOnConfigurationChange(context);
     }
 
@@ -323,17 +369,25 @@
         mUnfocusedRange = new Range(res.getFloat(R.integer.recents_layout_unfocused_range_min),
                 res.getFloat(R.integer.recents_layout_unfocused_range_max));
         mFocusState = getInitialFocusState();
-        mInitialTopPeekHeight = res.getDimensionPixelSize(R.dimen.recents_initial_top_peek_size);
-        mInitialBottomPeekHeight =
-                res.getDimensionPixelSize(R.dimen.recents_initial_bottom_peek_size);
-        mFocusedTopPeekHeight =
-                res.getDimensionPixelSize(R.dimen.recents_layout_focused_top_peek_size);
-        mFocusedBottomTaskPeekHeight =
-                res.getDimensionPixelSize(R.dimen.recents_layout_focused_bottom_task_peek_size);
-        mHeaderBarHeight = res.getDimensionPixelSize(R.dimen.recents_task_bar_height);
-
-        mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
-        mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max);
+        mFocusedTopPeekHeight = res.getDimensionPixelSize(R.dimen.recents_layout_top_peek_size);
+        mFocusedBottomPeekHeight =
+                res.getDimensionPixelSize(R.dimen.recents_layout_bottom_peek_size);
+        mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_layout_z_min);
+        mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_layout_z_max);
+        mBaseInitialTopOffset = getDimensionForDevice(res,
+                R.dimen.recents_layout_initial_top_offset_phone_port,
+                R.dimen.recents_layout_initial_top_offset_phone_land,
+                R.dimen.recents_layout_initial_top_offset_tablet,
+                R.dimen.recents_layout_initial_top_offset_tablet,
+                R.dimen.recents_layout_initial_top_offset_tablet,
+                R.dimen.recents_layout_initial_top_offset_tablet);
+        mBaseInitialBottomOffset = getDimensionForDevice(res,
+                R.dimen.recents_layout_initial_bottom_offset_phone_port,
+                R.dimen.recents_layout_initial_bottom_offset_phone_land,
+                R.dimen.recents_layout_initial_bottom_offset_tablet,
+                R.dimen.recents_layout_initial_bottom_offset_tablet,
+                R.dimen.recents_layout_initial_bottom_offset_tablet,
+                R.dimen.recents_layout_initial_bottom_offset_tablet);
         mFreeformLayoutAlgorithm.reloadOnConfigurationChange(context);
     }
 
@@ -372,52 +426,52 @@
     }
 
     /**
-     * Computes the stack and task rects.  The given task stack bounds is the whole bounds not
-     * including the search bar.
+     * Computes the stack and task rects.  The given task stack bounds already has the top/right
+     * insets and left/right padding already applied.
      */
-    public void initialize(Rect taskStackBounds, StackState state) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        int widthPadding = (int) (config.taskStackWidthPaddingPct * taskStackBounds.width());
-        int heightPadding = mContext.getResources().getDimensionPixelSize(
-                R.dimen.recents_stack_top_padding);
+    public void initialize(Rect windowRect, Rect taskStackBounds, StackState state) {
+        SystemServicesProxy ssp = Recents.getSystemServices();
         Rect lastStackRect = new Rect(mStackRect);
+        Rect displayRect = ssp.getDisplayRect();
 
-        // The freeform height is the visible height (not including system insets) - padding above
-        // freeform and below stack - gap between the freeform and stack
+        int topMargin = getScaleForExtent(windowRect, displayRect, mBaseTopMargin, mMinMargin, HEIGHT);
+        int bottomMargin = getScaleForExtent(windowRect, displayRect, mBaseBottomMargin, mMinMargin,
+                HEIGHT);
+        mInitialTopOffset = getScaleForExtent(windowRect, displayRect, mBaseInitialTopOffset,
+                mMinMargin, HEIGHT);
+        mInitialBottomOffset = mBaseInitialBottomOffset;
+
+        // Compute the stack bounds
         mState = state;
-        mStackTopOffset = mFocusedTopPeekHeight + heightPadding;
-        mStackBottomOffset = mSystemInsets.bottom + heightPadding;
-        state.computeRects(mFreeformRect, mStackRect, taskStackBounds, widthPadding, heightPadding,
-                mStackBottomOffset);
-        // The history button will take the full un-padded header space above the stack
-        mHistoryButtonRect.set(mStackRect.left, mStackRect.top - heightPadding,
+        mStackBottomOffset = mSystemInsets.bottom + bottomMargin;
+        state.computeRects(mFreeformRect, mStackRect, taskStackBounds, topMargin,
+                mFreeformStackGap, mStackBottomOffset);
+
+        // The stack action button will take the full un-padded header space above the stack
+        mStackActionButtonRect.set(mStackRect.left, mStackRect.top - topMargin,
                 mStackRect.right, mStackRect.top + mFocusedTopPeekHeight);
 
-        // Anchor the task rect to the top-center of the non-freeform stack rect
-        float aspect = (float) (taskStackBounds.width() - mSystemInsets.left - mSystemInsets.right)
-                / (taskStackBounds.height() - mSystemInsets.bottom);
-        int width = mStackRect.width();
-        int minHeight = mStackRect.height() - mFocusedTopPeekHeight - mStackBottomOffset;
-        int height = (int) Math.min(width / aspect, minHeight);
-        mTaskRect.set(mStackRect.left, mStackRect.top,
-                mStackRect.left + width, mStackRect.top + height);
+        // Anchor the task rect top aligned to the non-freeform stack rect
+        float aspect = (float) (windowRect.width() - (mSystemInsets.left + mSystemInsets.right)) /
+                (windowRect.height() - (mSystemInsets.top + mSystemInsets.bottom));
+        int minHeight = mStackRect.height() - mInitialTopOffset - mStackBottomOffset;
+        int height = (int) Math.min(mStackRect.width() / aspect, minHeight);
+        mTaskRect.set(mStackRect.left, mStackRect.top, mStackRect.right, mStackRect.top + height);
 
         // Short circuit here if the stack rects haven't changed so we don't do all the work below
-        if (lastStackRect.equals(mStackRect)) {
-            return;
+        if (!lastStackRect.equals(mStackRect)) {
+            // Reinitialize the focused and unfocused curves
+            mUnfocusedCurve = constructUnfocusedCurve();
+            mUnfocusedCurveInterpolator = new FreePathInterpolator(mUnfocusedCurve);
+            mFocusedCurve = constructFocusedCurve();
+            mFocusedCurveInterpolator = new FreePathInterpolator(mFocusedCurve);
+            mUnfocusedDimCurve = constructUnfocusedDimCurve();
+            mUnfocusedDimCurveInterpolator = new FreePathInterpolator(mUnfocusedDimCurve);
+            mFocusedDimCurve = constructFocusedDimCurve();
+            mFocusedDimCurveInterpolator = new FreePathInterpolator(mFocusedDimCurve);
+
+            updateFrontBackTransforms();
         }
-
-        // Reinitialize the focused and unfocused curves
-        mUnfocusedCurve = constructUnfocusedCurve();
-        mUnfocusedCurveInterpolator = new FreePathInterpolator(mUnfocusedCurve);
-        mFocusedCurve = constructFocusedCurve();
-        mFocusedCurveInterpolator = new FreePathInterpolator(mFocusedCurve);
-        mUnfocusedDimCurve = constructUnfocusedDimCurve();
-        mUnfocusedDimCurveInterpolator = new FreePathInterpolator(mUnfocusedDimCurve);
-        mFocusedDimCurve = constructFocusedDimCurve();
-        mFocusedDimCurveInterpolator = new FreePathInterpolator(mFocusedDimCurve);
-
-        updateFrontBackTransforms();
     }
 
     /**
@@ -435,7 +489,7 @@
         ArrayList<Task> tasks = stack.getStackTasks();
         if (tasks.isEmpty()) {
             mFrontMostTaskP = 0;
-            mMinScrollP = mMaxScrollP = 0;
+            mMinScrollP = mMaxScrollP = mInitialScrollP = 0;
             mNumStackTasks = mNumFreeformTasks = 0;
             return;
         }
@@ -492,8 +546,7 @@
             // Set the max scroll to be the point where the front most task is visible with the
             // stack bottom offset
             int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
-            float maxBottomOffsetPct = (float) maxBottomOffset / mStackRect.height();
-            float maxBottomNormX = mUnfocusedCurveInterpolator.getX(maxBottomOffsetPct);
+            float maxBottomNormX = getNormalizedXFromUnfocusedY(maxBottomOffset, FROM_BOTTOM);
             mUnfocusedRange.offset(0f);
             mMinScrollP = 0;
             mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
@@ -502,34 +555,19 @@
                     launchState.launchedFromAppDocked;
             if (scrollToFront) {
                 mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
+                mInitialNormX = null;
             } else {
-                mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP, mMaxScrollP);
-            }
+                float normX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
+                mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2)) -
+                        Math.max(0, mUnfocusedRange.getAbsoluteX(normX)));
 
-            // Set the initial scroll to the predefined state (which differs from the stack)
-            int initialPeekOffset = mStackRect.height() - mInitialTopPeekHeight;
-            float initialPeekOffsetPct = (float) initialPeekOffset / mStackRect.height();
-            float initialPeekOffsetNormX = mUnfocusedCurveInterpolator.getX(initialPeekOffsetPct);
-            float initialFocusedOffset = mStackRect.height() - mInitialTopPeekHeight -
-                    (mHeaderBarHeight * 1f) + 1;
-            float initialFocusedOffsetPct = initialFocusedOffset / mStackRect.height();
-            float initialFocusedNormX = mUnfocusedCurveInterpolator.getX(initialFocusedOffsetPct);
-            float initialBottomOffset = mStackBottomOffset +
-                    (ssp.hasDockedTask()
-                        ? mHeaderBarHeight
-                        : mInitialBottomPeekHeight);
-            float initialBottomOffsetPct = initialBottomOffset / mStackRect.height();
-            float initialBottomNormX = mUnfocusedCurveInterpolator.getX(initialBottomOffsetPct);
-            /*
-            // If we want to offset the top card slightly
-            mInitialNormX = scrollToFront
-                    ? new float[] { initialFocusedNormX, initialPeekOffsetNormX, 0f }
-                    : new float[] { initialBottomNormX, initialFocusedNormX,
-                            initialPeekOffsetNormX, 0f };
-            */
-            mInitialNormX = scrollToFront
-                    ? new float[] { initialFocusedNormX, initialPeekOffsetNormX, 0f }
-                    : new float[] { initialBottomNormX, 0.5f, 0f };
+                // Set the initial scroll to the predefined state (which differs from the stack)
+                mInitialNormX = new float[] {
+                        getNormalizedXFromUnfocusedY(mSystemInsets.bottom + mInitialBottomOffset,
+                                FROM_BOTTOM),
+                        normX
+                };
+            }
         }
     }
 
@@ -669,7 +707,7 @@
         Range currentRange = getInitialFocusState() > 0f ? mFocusedRange : mUnfocusedRange;
         currentRange.offset(mInitialScrollP);
         int taskBarHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.recents_task_bar_height);
+                R.dimen.recents_task_view_header_height);
         int numVisibleTasks = Math.max(mNumFreeformTasks, 1);
         int numVisibleThumbnails = Math.max(mNumFreeformTasks, 1);
         float prevScreenY = Integer.MAX_VALUE;
@@ -814,7 +852,7 @@
             // in screen space
             float tmpP = (mMinScrollP - stackScroll) / mNumStackTasks;
             int centerYOffset = (mStackRect.top - mTaskRect.top) +
-                    (mStackRect.height() - mTaskRect.height()) / 2;
+                    (mStackRect.height() - mSystemInsets.bottom - mTaskRect.height()) / 2;
             y = centerYOffset + getYForDeltaP(tmpP, 0);
             z = mMaxTranslationZ;
             dimAlpha = 0f;
@@ -869,6 +907,25 @@
     }
 
     /**
+     * Returns the original scroll progress to scroll to such that the top of the task is at the top
+     * of the stack.
+     */
+    float getStackScrollForTaskIgnoreOverrides(Task t) {
+        return (float) mTaskIndexMap.get(t.key.id, 0);
+    }
+
+    /**
+     * Returns the scroll progress to scroll to such that the top of the task at the initial top
+     * offset (which is at the task's brightest point).
+     */
+    float getStackScrollForTaskAtInitialOffset(Task t) {
+        float normX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
+        mUnfocusedRange.offset(0f);
+        return Utilities.clamp((float) mTaskIndexMap.get(t.key.id, 0) - Math.max(0,
+                mUnfocusedRange.getAbsoluteX(normX)), mMinScrollP, mMaxScrollP);
+    }
+
+    /**
      * Maps a movement in screen y, relative to {@param downY}, to a movement in along the arc
      * length of the curve.  We know the curve is mostly flat, so we just map the length of the
      * screen along the arc-length proportionally (1/arclength).
@@ -890,6 +947,81 @@
     }
 
     /**
+     * Returns the task stack bounds in the current orientation.  This rect takes into account the
+     * top and right system insets (but not the bottom inset) and left/right paddings, but _not_
+     * the top/bottom padding or insets.
+     */
+    public void getTaskStackBounds(Rect windowRect, int topInset, int rightInset,
+            Rect taskStackBounds) {
+        taskStackBounds.set(windowRect.left, windowRect.top + topInset,
+                windowRect.right - rightInset, windowRect.bottom);
+
+        // Ensure that the new width is at most the smaller display edge size
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        Rect displayRect = ssp.getDisplayRect();
+        int sideMargin = getScaleForExtent(windowRect, displayRect, mBaseSideMargin, mMinMargin,
+                WIDTH);
+        int targetStackWidth = taskStackBounds.width() - 2 * sideMargin;
+        if (ssp.getDisplayOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+            // If we are in landscape, calculate the width of the stack in portrait and ensure that
+            // we are not larger than that size
+            Rect portraitDisplayRect = new Rect(0, 0,
+                    Math.min(displayRect.width(), displayRect.height()),
+                    Math.max(displayRect.width(), displayRect.height()));
+            int portraitSideMargin = getScaleForExtent(portraitDisplayRect, portraitDisplayRect,
+                    mBaseSideMargin, mMinMargin, WIDTH);
+            targetStackWidth = Math.min(targetStackWidth,
+                    portraitDisplayRect.width() - 2 * portraitSideMargin);
+        }
+        taskStackBounds.inset((taskStackBounds.width() - targetStackWidth) / 2, 0);
+    }
+
+    /**
+     * Retrieves resources that are constant regardless of the current configuration of the device.
+     */
+    public static int getDimensionForDevice(Resources res, int phoneResId,
+            int tabletResId, int xlargeTabletResId) {
+        return getDimensionForDevice(res, phoneResId, phoneResId, tabletResId, tabletResId,
+                xlargeTabletResId, xlargeTabletResId);
+    }
+
+    /**
+     * Retrieves resources that are constant regardless of the current configuration of the device.
+     */
+    public static int getDimensionForDevice(Resources res, int phonePortResId, int phoneLandResId,
+            int tabletPortResId, int tabletLandResId, int xlargeTabletPortResId,
+            int xlargeTabletLandResId) {
+        RecentsConfiguration config = Recents.getConfiguration();
+        boolean isLandscape = Recents.getSystemServices().getDisplayOrientation() ==
+                Configuration.ORIENTATION_LANDSCAPE;
+        if (config.isXLargeScreen) {
+            return res.getDimensionPixelSize(isLandscape
+                    ? xlargeTabletLandResId
+                    : xlargeTabletPortResId);
+        } else if (config.isLargeScreen) {
+            return res.getDimensionPixelSize(isLandscape
+                    ? tabletLandResId
+                    : tabletPortResId);
+        } else {
+            return res.getDimensionPixelSize(isLandscape
+                    ? phoneLandResId
+                    : phonePortResId);
+        }
+    }
+
+    /**
+     * Returns the normalized x on the unfocused curve given an absolute Y position (relative to the
+     * stack height).
+     */
+    private float getNormalizedXFromUnfocusedY(float y, @AnchorSide int fromSide) {
+        float offset = (fromSide == FROM_TOP)
+                ? mStackRect.height() - y
+                : y;
+        float offsetPct = offset / mStackRect.height();
+        return mUnfocusedCurveInterpolator.getX(offsetPct);
+    }
+
+    /**
      * Creates a new path for the focused curve.
      */
     private Path constructFocusedCurve() {
@@ -897,13 +1029,12 @@
         // linear pieces that goes from (0,1) through (0.5, peek height offset),
         // (0.5, bottom task offsets), and (1,0).
         float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
-        float bottomPeekHeightPct = Math.max(
-                mSystemInsets.bottom + mFocusedRange.relativeMax * mFocusedBottomTaskPeekHeight,
-                mStackBottomOffset + mFocusedBottomTaskPeekHeight) / mStackRect.height();
+        float bottomPeekHeightPct = (float) (mStackBottomOffset + mFocusedBottomPeekHeight) /
+                mStackRect.height();
         Path p = new Path();
         p.moveTo(0f, 1f);
         p.lineTo(0.5f, 1f - topPeekHeightPct);
-        p.lineTo(0.5f + (0.5f / mFocusedRange.relativeMax), bottomPeekHeightPct);
+        p.lineTo(1f - (0.5f / mFocusedRange.relativeMax), bottomPeekHeightPct);
         p.lineTo(1f, 0f);
         return p;
     }
@@ -919,16 +1050,16 @@
         // the control point of the second bezier such that between it and a first known point,
         // there is a tangent at (0.5, peek height offset).
         float cpoint1X = 0.4f;
-        float cpoint1Y = 1f;
-        float peekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
-        float slope = ((1f - peekHeightPct) - cpoint1Y) / (0.5f - cpoint1X);
+        float cpoint1Y = 0.975f;
+        float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
+        float slope = ((1f - topPeekHeightPct) - cpoint1Y) / (0.5f - cpoint1X);
         float b = 1f - slope * cpoint1X;
         float cpoint2X = 0.65f;
         float cpoint2Y = slope * cpoint2X + b;
         Path p = new Path();
         p.moveTo(0f, 1f);
-        p.cubicTo(0f, 1f, cpoint1X, cpoint1Y, 0.5f, 1f - peekHeightPct);
-        p.cubicTo(0.5f, 1f - peekHeightPct, cpoint2X, cpoint2Y, 1f, 0f);
+        p.cubicTo(0f, 1f, cpoint1X, cpoint1Y, 0.5f, 1f - topPeekHeightPct);
+        p.cubicTo(0.5f, 1f - topPeekHeightPct, cpoint2X, cpoint2Y, 1f, 0f);
         return p;
     }
 
@@ -950,15 +1081,32 @@
      * Creates a new path for the unfocused dim curve.
      */
     private Path constructUnfocusedDimCurve() {
+        float focusX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
+        float cpoint2X = focusX + (1f - focusX) / 2;
         Path p = new Path();
         // The unfocused dim interpolator starts at max dim, reduces to zero at 0.5 (the focused
         // task), then goes back to max dim towards the front of the stack
         p.moveTo(0f, MAX_DIM);
-        p.cubicTo(0.1f, MAX_DIM, 0.4f, 0.0f, 0.5f, 0f);
-        p.cubicTo(0.6f, 0f, 0.9f, MAX_DIM / 2f, 1f, MAX_DIM / 2f);
+        p.cubicTo(focusX * 0.5f, MAX_DIM, focusX * 0.75f, MAX_DIM * 0.75f, focusX, 0f);
+        p.cubicTo(cpoint2X, 0f, cpoint2X, MED_DIM, 1f, MED_DIM);
         return p;
     }
 
+    /**
+     * Scales the given {@param value} to the scale of the {@param instance} rect relative to the
+     * {@param other} rect in the {@param extent} side.
+     */
+    private int getScaleForExtent(Rect instance, Rect other, int value, int minValue,
+                                  @Extent int extent) {
+        if (extent == WIDTH) {
+            float scale = Utilities.clamp01((float) instance.width() / other.width());
+            return Math.max(minValue, (int) (scale * value));
+        } else if (extent == HEIGHT) {
+            float scale = Utilities.clamp01((float) instance.height() / other.height());
+            return Math.max(minValue, (int) (scale * value));
+        }
+        return value;
+    }
 
     /**
      * Updates the current transforms that would put a TaskView at the front and back of the stack.
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 0b20d21..9032871 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -22,6 +22,7 @@
 
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
+import android.annotation.IntDef;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
@@ -59,8 +60,7 @@
 import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
 import com.android.systemui.recents.events.activity.EnterRecentsTaskStackAnimationCompletedEvent;
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
-import com.android.systemui.recents.events.activity.HideHistoryButtonEvent;
-import com.android.systemui.recents.events.activity.HideHistoryEvent;
+import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
@@ -68,8 +68,7 @@
 import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
 import com.android.systemui.recents.events.activity.PackagesChangedEvent;
-import com.android.systemui.recents.events.activity.ShowHistoryButtonEvent;
-import com.android.systemui.recents.events.activity.ShowHistoryEvent;
+import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
 import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
 import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
 import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
@@ -84,12 +83,13 @@
 import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
 import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
 import com.android.systemui.recents.misc.DozeTrigger;
-import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -106,23 +106,36 @@
     private final static String KEY_SAVED_STATE_LAYOUT_STACK_SCROLL =
             "saved_instance_state_layout_stack_scroll";
 
-    // The thresholds at which to show/hide the history button.
-    private static final float SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
-    private static final float HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
+    // The thresholds at which to show/hide the stack action button.
+    private static final float SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f;
+    private static final float HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f;
 
     public static final int DEFAULT_SYNC_STACK_DURATION = 200;
     private static final int DRAG_SCALE_DURATION = 175;
-    private static final float DRAG_SCALE_FACTOR = 1.05f;
+    static final float DRAG_SCALE_FACTOR = 1.05f;
 
-    private static final int LAUNCH_NEXT_SCROLL_BASE_DURATION = 200;
+    private static final int LAUNCH_NEXT_SCROLL_BASE_DURATION = 216;
     private static final int LAUNCH_NEXT_SCROLL_INCR_DURATION = 32;
 
     private static final ArraySet<Task.TaskKey> EMPTY_TASK_SET = new ArraySet<>();
 
+    // The actions to perform when resetting to initial state,
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({INITIAL_STATE_UPDATE_NONE, INITIAL_STATE_UPDATE_ALL, INITIAL_STATE_UPDATE_LAYOUT_ONLY})
+    public @interface InitialStateAction {}
+    /** Do not update the stack and layout to the initial state. */
+    private static final int INITIAL_STATE_UPDATE_NONE = 0;
+    /** Update both the stack and layout to the initial state. */
+    private static final int INITIAL_STATE_UPDATE_ALL = 1;
+    /** Update only the layout to the initial state. */
+    private static final int INITIAL_STATE_UPDATE_LAYOUT_ONLY = 2;
+
     LayoutInflater mInflater;
     TaskStack mStack = new TaskStack();
     @ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
     TaskStackLayoutAlgorithm mLayoutAlgorithm;
+    // The stable layout algorithm is only used to calculate the task rect with the stable bounds
+    TaskStackLayoutAlgorithm mStableLayoutAlgorithm;
     @ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_")
     TaskStackViewScroller mStackScroller;
     @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
@@ -151,6 +164,9 @@
     @ViewDebug.ExportedProperty(category="recents")
     boolean mAwaitingFirstLayout = true;
     @ViewDebug.ExportedProperty(category="recents")
+    @InitialStateAction
+    int mInitialState = INITIAL_STATE_UPDATE_ALL;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mInMeasureLayout = false;
     @ViewDebug.ExportedProperty(category="recents")
     boolean mEnterAnimationComplete = false;
@@ -165,11 +181,18 @@
     // The current stack bounds are dynamic and may change as the user drags and drops
     @ViewDebug.ExportedProperty(category="recents")
     private Rect mStackBounds = new Rect();
+    // The current window bounds at the point we were measured
+    @ViewDebug.ExportedProperty(category="recents")
+    private Rect mStableWindowRect = new Rect();
+    // The current window bounds are dynamic and may change as the user drags and drops
+    @ViewDebug.ExportedProperty(category="recents")
+    private Rect mWindowRect = new Rect();
 
     private Rect mTmpRect = new Rect();
     private ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
     private List<TaskView> mTmpTaskViews = new ArrayList<>();
     private TaskViewTransform mTmpTransform = new TaskViewTransform();
+    private ArrayList<TaskViewTransform> mTmpTaskTransforms = new ArrayList<>();
     private int[] mTmpIntPair = new int[2];
 
     // A convenience update listener to request updating clipping of tasks
@@ -219,6 +242,7 @@
         mViewPool = new ViewPool<>(context, this);
         mInflater = LayoutInflater.from(context);
         mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
+        mStableLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null);
         mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
         mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
         mAnimationHelper = new TaskStackAnimationHelper(context, this);
@@ -251,41 +275,6 @@
         }
     }
 
-    /**
-     * Called only if we are resuming Recents.
-     */
-    void onResume(boolean isResumingFromVisible) {
-        if (!isResumingFromVisible) {
-            // Reset the focused task
-            resetFocusedTask(getFocusedTask());
-        }
-
-        // Reset the state of each of the task views
-        List<TaskView> taskViews = new ArrayList<>();
-        taskViews.addAll(getTaskViews());
-        taskViews.addAll(mViewPool.getViews());
-        for (int i = taskViews.size() - 1; i >= 0; i--) {
-            taskViews.get(i).onResume(isResumingFromVisible);
-        }
-
-        // Reset the stack state
-        readSystemFlags();
-        mTaskViewsClipDirty = true;
-        mEnterAnimationComplete = false;
-        mUIDozeTrigger.stopDozing();
-        if (isResumingFromVisible) {
-            // Animate in the freeform workspace
-            int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha;
-            animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150,
-                    Interpolators.FAST_OUT_SLOW_IN));
-        } else {
-            mStackScroller.reset();
-            mLayoutAlgorithm.reset();
-            mAwaitingFirstLayout = true;
-            requestLayout();
-        }
-    }
-
     @Override
     protected void onAttachedToWindow() {
         EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
@@ -300,31 +289,54 @@
     }
 
     /**
+     * Called from RecentsActivity when it is relaunched.
+     */
+    void onReload(boolean isResumingFromVisible) {
+        if (!isResumingFromVisible) {
+            // Reset the focused task
+            resetFocusedTask(getFocusedTask());
+        }
+
+        // Reset the state of each of the task views
+        List<TaskView> taskViews = new ArrayList<>();
+        taskViews.addAll(getTaskViews());
+        taskViews.addAll(mViewPool.getViews());
+        for (int i = taskViews.size() - 1; i >= 0; i--) {
+            taskViews.get(i).onReload(isResumingFromVisible);
+        }
+
+        // Reset the stack state
+        readSystemFlags();
+        mTaskViewsClipDirty = true;
+        mEnterAnimationComplete = false;
+        mUIDozeTrigger.stopDozing();
+        if (isResumingFromVisible) {
+            // Animate in the freeform workspace
+            int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha;
+            animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150,
+                    Interpolators.FAST_OUT_SLOW_IN));
+        } else {
+            mStackScroller.reset();
+            mStableLayoutAlgorithm.reset();
+            mLayoutAlgorithm.reset();
+        }
+
+        // Since we always animate to the same place in (the initial state), always reset the stack
+        // to the initial state when resuming
+        mAwaitingFirstLayout = true;
+        mInitialState = INITIAL_STATE_UPDATE_ALL;
+        requestLayout();
+    }
+
+    /**
      * Sets the stack tasks of this TaskStackView from the given TaskStack.
      */
-    public void setTasks(TaskStack stack, boolean notifyStackChanges, boolean relayoutTaskStack) {
+    public void setTasks(TaskStack stack, boolean allowNotifyStackChanges) {
         boolean isInitialized = mLayoutAlgorithm.isInitialized();
+        // Only notify if we are already initialized, otherwise, everything will pick up all the
+        // new and old tasks when we next layout
         mStack.setTasks(getContext(), stack.computeAllTasksList(),
-                notifyStackChanges && isInitialized);
-        if (isInitialized) {
-            // Only update the layout if we are notifying, otherwise, we will update it in the next
-            // measure/layout pass
-            updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
-            updateToInitialState();
-
-            if (relayoutTaskStack) {
-                relayoutTaskViews(AnimationProps.IMMEDIATE);
-
-                // Rebind all the task views.  This will not trigger new resources to be loaded
-                // unless they have actually changed
-                List<TaskView> taskViews = getTaskViews();
-                int taskViewCount = taskViews.size();
-                for (int i = 0; i < taskViewCount; i++) {
-                    TaskView tv = taskViews.get(i);
-                    bindTaskView(tv, tv.getTask());
-                }
-            }
-        }
+                allowNotifyStackChanges && isInitialized);
     }
 
     /** Returns the task stack. */
@@ -335,8 +347,10 @@
     /**
      * Updates this TaskStackView to the initial state.
      */
-    public void updateToInitialState() {
-        mStackScroller.setStackScrollToInitialState();
+    public void updateToInitialState(boolean scrollToInitialState) {
+        if (scrollToInitialState) {
+            mStackScroller.setStackScrollToInitialState();
+        }
         mLayoutAlgorithm.updateToInitialState(mStack.getStackTasks());
     }
 
@@ -622,15 +636,17 @@
     }
 
     /**
-     * Relayout the the visible {@link TaskView}s to their current transforms as specified by the
-     * {@link TaskStackLayoutAlgorithm} with the given {@param animation}. This call cancels any
-     * animations that are current running on those task views, and will ensure that the children
-     * {@link TaskView}s will match the set of visible tasks in the stack.
-     *
-     * @see #relayoutTaskViews(AnimationProps, ArraySet<Task.TaskKey>)
+     * @see #relayoutTaskViews(AnimationProps, ArraySet<Task.TaskKey>, boolean)
      */
     void relayoutTaskViews(AnimationProps animation) {
-        relayoutTaskViews(animation, mIgnoreTasks);
+        relayoutTaskViews(animation, mIgnoreTasks, false /* ignoreTaskOverrides */);
+    }
+
+    /**
+     * @see #relayoutTaskViews(AnimationProps, ArraySet<Task.TaskKey>, boolean)
+     */
+    void relayoutTaskViews(AnimationProps animation, ArraySet<Task.TaskKey> ignoreTasksSet) {
+        relayoutTaskViews(animation, ignoreTasksSet, false /* ignoreTaskOverrides */);
     }
 
     /**
@@ -641,13 +657,14 @@
      *
      * @param ignoreTasksSet the set of tasks to ignore in the relayout
      */
-    void relayoutTaskViews(AnimationProps animation, ArraySet<Task.TaskKey> ignoreTasksSet) {
+    void relayoutTaskViews(AnimationProps animation, ArraySet<Task.TaskKey> ignoreTasksSet,
+            boolean ignoreTaskOverrides) {
         // If we had a deferred animation, cancel that
         mDeferredTaskViewLayoutAnimation = null;
 
         // Synchronize the current set of TaskViews
         bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTasksSet,
-                false /* ignoreTaskOverrides */);
+                ignoreTaskOverrides /* ignoreTaskOverrides */);
 
         // Animate them to their final transforms with the given animation
         List<TaskView> taskViews = getTaskViews();
@@ -761,8 +778,6 @@
      * Updates the clip for each of the task views from back to front.
      */
     private void clipTaskViews() {
-        RecentsConfiguration config = Recents.getConfiguration();
-
         // Update the clip on each task child
         List<TaskView> taskViews = getTaskViews();
         TaskView tmpTv = null;
@@ -1059,8 +1074,10 @@
             event.setContentDescription(frontMostTask.getTask().title);
         }
         event.setItemCount(mStack.getTaskCount());
-        event.setScrollY(mStackScroller.mScroller.getCurrY());
-        event.setMaxScrollY(mStackScroller.progressToScrollRange(mLayoutAlgorithm.mMaxScrollP));
+
+        int stackHeight = mLayoutAlgorithm.mStackRect.height();
+        event.setScrollY((int) (mStackScroller.getStackScroll() * stackHeight));
+        event.setMaxScrollY((int) (mLayoutAlgorithm.mMaxScrollP * stackHeight));
     }
 
     @Override
@@ -1161,23 +1178,12 @@
     }
 
     /**
-     * Updates the expected task stack bounds for this stack view.
+     * Updates the system insets.
      */
-    public void setTaskStackBounds(Rect taskStackBounds, Rect systemInsets) {
-        // We can get spurious measure passes with the old bounds when docking, and since we are
-        // using the current stack bounds during drag and drop, don't overwrite them until we
-        // actually get new bounds
-        boolean requiresLayout = false;
-        if (!taskStackBounds.equals(mStableStackBounds)) {
-            mStableStackBounds.set(taskStackBounds);
-            mStackBounds.set(taskStackBounds);
-            requiresLayout = true;
-        }
+    public void setSystemInsets(Rect systemInsets) {
         if (!systemInsets.equals(mLayoutAlgorithm.mSystemInsets)) {
+            mStableLayoutAlgorithm.setSystemInsets(systemInsets);
             mLayoutAlgorithm.setSystemInsets(systemInsets);
-            requiresLayout = true;
-        }
-        if (requiresLayout) {
             requestLayout();
         }
     }
@@ -1192,18 +1198,30 @@
         int width = MeasureSpec.getSize(widthMeasureSpec);
         int height = MeasureSpec.getSize(heightMeasureSpec);
 
+        // Update the stable stack bounds, but only update the current stack bounds if the stable
+        // bounds have changed.  This is because we may get spurious measures while dragging where
+        // our current stack bounds reflect the target drop region.
+        mLayoutAlgorithm.getTaskStackBounds(new Rect(0, 0, width, height),
+                mLayoutAlgorithm.mSystemInsets.top, mLayoutAlgorithm.mSystemInsets.right, mTmpRect);
+        if (!mTmpRect.equals(mStableStackBounds)) {
+            mStableStackBounds.set(mTmpRect);
+            mStackBounds.set(mTmpRect);
+            mStableWindowRect.set(0, 0, width, height);
+            mWindowRect.set(0, 0, width, height);
+        }
+
         // Compute the rects in the stack algorithm
-        mLayoutAlgorithm.initialize(mStackBounds,
+        mStableLayoutAlgorithm.initialize(mStableWindowRect, mStableStackBounds,
+                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+        mLayoutAlgorithm.initialize(mWindowRect, mStackBounds,
                 TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
         updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
 
         // If this is the first layout, then scroll to the front of the stack, then update the
         // TaskViews with the stack so that we can lay them out
-        // TODO: The second check is a workaround for wacky layouts that we get while docking via
-        //       long pressing the recents button
-        if (mAwaitingFirstLayout ||
-                (mStackScroller.getStackScroll() == mLayoutAlgorithm.mInitialScrollP)) {
-            updateToInitialState();
+        if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE) {
+            updateToInitialState(mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY);
+            mInitialState = INITIAL_STATE_UPDATE_NONE;
         }
 
         // Rebind all the views, including the ignore ones
@@ -1232,20 +1250,14 @@
         } else {
             mTmpRect.setEmpty();
         }
+        Rect taskRect = mStableLayoutAlgorithm.mTaskRect;
         tv.measure(
-                MeasureSpec.makeMeasureSpec(
-                        mLayoutAlgorithm.mTaskRect.width() + mTmpRect.left + mTmpRect.right,
+                MeasureSpec.makeMeasureSpec(taskRect.width() + mTmpRect.left + mTmpRect.right,
                         MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(
-                        mLayoutAlgorithm.mTaskRect.height() + mTmpRect.top + mTmpRect.bottom,
+                MeasureSpec.makeMeasureSpec(taskRect.height() + mTmpRect.top + mTmpRect.bottom,
                         MeasureSpec.EXACTLY));
     }
 
-    /**
-     * This is called with the size of the space not including the top or right insets, or the
-     * search bar height in portrait (but including the search bar width in landscape, since we want
-     * to draw under it.
-     */
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         // Layout each of the TaskViews
@@ -1281,7 +1293,8 @@
         } else {
             mTmpRect.setEmpty();
         }
-        Rect taskRect = mLayoutAlgorithm.mTaskRect;
+        Rect taskRect = mStableLayoutAlgorithm.mTaskRect;
+        tv.cancelTransformAnimation();
         tv.layout(taskRect.left - mTmpRect.left, taskRect.top - mTmpRect.top,
                 taskRect.right + mTmpRect.right, taskRect.bottom + mTmpRect.bottom);
     }
@@ -1306,12 +1319,11 @@
                     false /* requestViewFocus */);
         }
 
-        // Update the history button visibility
-        if (shouldShowHistoryButton() &&
-                mStackScroller.getStackScroll() < SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD) {
-            EventBus.getDefault().send(new ShowHistoryButtonEvent(false /* translate */));
+        // Update the stack action button visibility
+        if (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
+            EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
         } else {
-            EventBus.getDefault().send(new HideHistoryButtonEvent());
+            EventBus.getDefault().send(new HideStackActionButtonEvent());
         }
     }
 
@@ -1433,9 +1445,19 @@
     }
 
     @Override
-    public void onHistoryTaskRemoved(TaskStack stack, Task removedTask,
-            AnimationProps animation) {
-        // To be implemented
+    public void onStackTasksUpdated(TaskStack stack) {
+        // Update the layout and immediately layout
+        updateLayoutAlgorithm(false /* boundScroll */);
+        relayoutTaskViews(AnimationProps.IMMEDIATE);
+
+        // Rebind all the task views.  This will not trigger new resources to be loaded
+        // unless they have actually changed
+        List<TaskView> taskViews = getTaskViews();
+        int taskViewCount = taskViews.size();
+        for (int i = 0; i < taskViewCount; i++) {
+            TaskView tv = taskViews.get(i);
+            bindTaskView(tv, tv.getTask());
+        }
     }
 
     /**** ViewPoolConsumer Implementation ****/
@@ -1572,13 +1594,12 @@
         mLayoutAlgorithm.updateFocusStateOnScroll(curScroll, curScroll - prevScroll);
 
         if (mEnterAnimationComplete) {
-            if (shouldShowHistoryButton() &&
-                    prevScroll > SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD &&
-                    curScroll <= SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD) {
-                EventBus.getDefault().send(new ShowHistoryButtonEvent(true /* translate */));
-            } else if (prevScroll < HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD &&
-                    curScroll >= HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD) {
-                EventBus.getDefault().send(new HideHistoryButtonEvent());
+            if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
+                    curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
+                EventBus.getDefault().send(new ShowStackActionButtonEvent(true /* translate */));
+            } else if (prevScroll < HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
+                    curScroll >= HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
+                EventBus.getDefault().send(new HideStackActionButtonEvent());
             }
         }
     }
@@ -1625,15 +1646,13 @@
             cancelAllTaskViewAnimations();
 
             final Task launchTask = mStack.getStackTasks().get(launchTaskIndex);
-            if (getChildViewForTask(launchTask) == null) {
-                List<TaskView> taskViews = getTaskViews();
-                int lastTaskIndex = !taskViews.isEmpty()
-                        ? mStack.indexOfStackTask(taskViews.get(taskViews.size() - 1).getTask())
-                        : mStack.getTaskCount() - 1;
-                int duration = LAUNCH_NEXT_SCROLL_BASE_DURATION +
-                        Math.abs(mStack.indexOfStackTask(launchTask) - lastTaskIndex)
-                                * LAUNCH_NEXT_SCROLL_INCR_DURATION;
-                mStackScroller.animateScroll(mLayoutAlgorithm.getStackScrollForTask(launchTask),
+            float curScroll = mStackScroller.getStackScroll();
+            float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(launchTask);
+            float absScrollDiff = Math.abs(targetScroll - curScroll);
+            if (getChildViewForTask(launchTask) == null || absScrollDiff > 0.35f) {
+                int duration = (int) (LAUNCH_NEXT_SCROLL_BASE_DURATION +
+                        absScrollDiff * LAUNCH_NEXT_SCROLL_INCR_DURATION);
+                mStackScroller.animateScroll(targetScroll,
                         duration, new Runnable() {
                             @Override
                             public void run() {
@@ -1757,32 +1776,38 @@
 
     public final void onBusEvent(DragDropTargetChangedEvent event) {
         AnimationProps animation = new AnimationProps(250, Interpolators.FAST_OUT_SLOW_IN);
+        boolean ignoreTaskOverrides = false;
         if (event.dropTarget instanceof TaskStack.DockState) {
             // Calculate the new task stack bounds that matches the window size that Recents will
             // have after the drop
             final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
             mStackBounds.set(dockState.getDockedTaskStackBounds(getMeasuredWidth(),
                     getMeasuredHeight(), mDividerSize, mLayoutAlgorithm.mSystemInsets,
-                    getResources()));
-            mLayoutAlgorithm.initialize(mStackBounds,
+                    mLayoutAlgorithm, getResources(), mWindowRect));
+            mLayoutAlgorithm.initialize(mWindowRect, mStackBounds,
                     TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
             updateLayoutAlgorithm(true /* boundScroll */);
+            ignoreTaskOverrides = true;
         } else {
             // Restore the pre-drag task stack bounds, but ensure that we don't layout the dragging
             // task view, so add it back to the ignore set after updating the layout
+            mWindowRect.set(mStableWindowRect);
             mStackBounds.set(mStableStackBounds);
             removeIgnoreTask(event.task);
-            mLayoutAlgorithm.initialize(mStackBounds,
+            mLayoutAlgorithm.initialize(mWindowRect, mStackBounds,
                     TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
             updateLayoutAlgorithm(true /* boundScroll */);
             addIgnoreTask(event.task);
         }
-        relayoutTaskViews(animation);
+        relayoutTaskViews(animation, mIgnoreTasks, ignoreTaskOverrides);
     }
 
     public final void onBusEvent(final DragEndEvent event) {
         // We don't handle drops on the dock regions
         if (event.dropTarget instanceof TaskStack.DockState) {
+            // However, we do need to reset the overrides, since the last state of this task stack
+            // view layout was ignoring task overrides (see DragDropTargetChangedEvent handler)
+            mLayoutAlgorithm.clearUnfocusedTaskOverrides();
             return;
         }
 
@@ -1888,22 +1913,6 @@
         }
     }
 
-    public final void onBusEvent(ShowHistoryEvent event) {
-        ReferenceCountedTrigger postAnimTrigger = new ReferenceCountedTrigger();
-        postAnimTrigger.addLastDecrementRunnable(new Runnable() {
-            @Override
-            public void run() {
-                setVisibility(View.INVISIBLE);
-            }
-        });
-        mAnimationHelper.startShowHistoryAnimation(postAnimTrigger);
-    }
-
-    public final void onBusEvent(HideHistoryEvent event) {
-        setVisibility(View.VISIBLE);
-        mAnimationHelper.startHideHistoryAnimation();
-    }
-
     public final void onBusEvent(MultiWindowStateChangedEvent event) {
         if (!event.inMultiWindow) {
             // Scroll the stack to the front to see the undocked task
@@ -1923,9 +1932,25 @@
     }
 
     public final void onBusEvent(ConfigurationChangedEvent event) {
+        mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
         mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
-        mLayoutAlgorithm.initialize(mStackBounds,
-                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+
+        // Notify the task views of the configuration change so they can reload their resources
+        if (!event.fromMultiWindow) {
+            mTmpTaskViews.clear();
+            mTmpTaskViews.addAll(getTaskViews());
+            mTmpTaskViews.addAll(mViewPool.getViews());
+            int taskViewCount = mTmpTaskViews.size();
+            for (int i = 0; i < taskViewCount; i++) {
+                mTmpTaskViews.get(i).onConfigurationChanged();
+            }
+        }
+
+        // Trigger a new layout and scroll to the initial state
+        mInitialState = event.fromMultiWindow
+                ? INITIAL_STATE_UPDATE_ALL
+                : INITIAL_STATE_UPDATE_LAYOUT_ONLY;
+        requestLayout();
     }
 
     /**
@@ -1993,13 +2018,6 @@
     }
 
     /**
-     * @return whether the history button should be visible
-     */
-    private boolean shouldShowHistoryButton() {
-        return !mStack.getHistoricalTasks().isEmpty();
-    }
-
-    /**
      * Reads current system flags related to accessibility and screen pinning.
      */
     private void readSystemFlags() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index 9be3542..583fb88 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -28,8 +28,6 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
 
 /* The scrolling logic for a TaskStackView */
@@ -189,7 +187,7 @@
         // Finish any current scrolling animations
         if (mScrollAnimator != null && mScrollAnimator.isRunning()) {
             setStackScroll(mFinalAnimatedScroll);
-            mScroller.startScroll(0, progressToScrollRange(mFinalAnimatedScroll), 0, 0, 0);
+            mScroller.forceFinished(true);
         }
         stopScroller();
         stopBoundScrollAnimation();
@@ -223,12 +221,6 @@
 
     /**** OverScroller ****/
 
-    // TODO: Remove
-    @Deprecated
-    int progressToScrollRange(float p) {
-        return (int) (p * mLayoutAlgorithm.mStackRect.height());
-    }
-
     /** Called from the view draw, computes the next scroll. */
     boolean computeScroll() {
         if (mScroller.computeScrollOffset()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 8635911..aed19c3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -121,7 +121,7 @@
         mScrollTouchSlop = configuration.getScaledTouchSlop();
         mWindowTouchSlop = configuration.getScaledWindowTouchSlop();
         mFlingAnimUtils = new FlingAnimationUtils(context, 0.2f);
-        mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_stack_overscroll);
+        mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_fling_overscroll_distance);
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) {
             @Override
             protected float getSize(View v) {
@@ -458,12 +458,13 @@
                 newStackScroll = stackScroller.getBoundedStackScroll(newStackScroll);
             } else if (pullStackForward) {
                 // Otherwise, offset the scroll by the movement of the anchor task
-                float anchorTaskScroll = layoutAlgorithm.getStackScrollForTask(anchorTask);
+                float anchorTaskScroll =
+                        layoutAlgorithm.getStackScrollForTaskIgnoreOverrides(anchorTask);
                 float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
                 if (layoutAlgorithm.getFocusState() != TaskStackLayoutAlgorithm.STATE_FOCUSED) {
                     // If we are focused, we don't want the front task to move, but otherwise, we
                     // allow the back task to move up, and the front task to move back
-                    stackScrollOffset /= 2;
+                    stackScrollOffset *= 0.75f;
                 }
                 newStackScroll = stackScroller.getBoundedStackScroll(stackScroller.getStackScroll()
                         + stackScrollOffset);
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 7584a2e..c085d80 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -16,13 +16,16 @@
 
 package com.android.systemui.recents.views;
 
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+
 import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
+import android.app.ActivityManager;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Color;
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.Point;
@@ -59,8 +62,6 @@
 
 import java.util.ArrayList;
 
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
 /**
  * A {@link TaskView} represents a fixed view of a task. Because the TaskView's layout is directed
  * solely by the {@link TaskStackView}, we make it a fixed size layout which allows relayouts down
@@ -129,8 +130,6 @@
 
     @ViewDebug.ExportedProperty(category="recents")
     float mDimAlpha;
-    PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP);
-    Paint mDimLayerPaint = new Paint();
     float mActionButtonTranslationZ;
 
     @ViewDebug.ExportedProperty(deepExport=true, prefix="task_")
@@ -193,15 +192,15 @@
         mCb = cb;
     }
 
-    /** Resets this TaskView for reuse. */
-    void onResume(boolean isResumingFromVisible) {
+    /**
+     * Called from RecentsActivity when it is relaunched.
+     */
+    void onReload(boolean isResumingFromVisible) {
         resetNoUserInteractionState();
         readSystemFlags();
         if (!isResumingFromVisible) {
             resetViewProperties();
-            setClipViewInStack(false);
         }
-        setCallbacks(null);
     }
 
     /** Gets the task */
@@ -239,6 +238,13 @@
         mActionButtonTranslationZ = mActionButtonView.getTranslationZ();
     }
 
+    /**
+     * Update the task view when the configuration changes.
+     */
+    void onConfigurationChanged() {
+        mHeaderView.onConfigurationChanged();
+    }
+
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
@@ -559,6 +565,13 @@
                 postAnimationTrigger.decrementOnAnimationEnd());
     }
 
+    @Override
+    public void onStartFrontTaskEnterAnimation(boolean screenPinningEnabled) {
+        if (screenPinningEnabled) {
+            showActionButton(false /* fadeIn */, 0 /* fadeInDuration */);
+        }
+    }
+
     /**** TaskCallbacks Implementation ****/
 
     public void onTaskBound(Task t) {
@@ -569,9 +582,9 @@
     }
 
     @Override
-    public void onTaskDataLoaded(Task task) {
+    public void onTaskDataLoaded(Task task, ActivityManager.TaskThumbnailInfo thumbnailInfo) {
         // Bind each of the views to the new task data
-        mThumbnailView.rebindToTask(mTask, mIsDisabledInSafeMode);
+        mThumbnailView.rebindToTask(mTask, thumbnailInfo, mIsDisabledInSafeMode);
         mHeaderView.rebindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
         mTaskDataLoaded = true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index b2a7d90..ddea4d9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -34,9 +34,11 @@
 import android.os.CountDownTimer;
 import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
+import android.view.Gravity;
 import android.view.View;
 import android.view.ViewAnimationUtils;
 import android.view.ViewDebug;
+import android.view.ViewGroup;
 import android.view.ViewStub;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -153,6 +155,8 @@
     // Header drawables
     @ViewDebug.ExportedProperty(category="recents")
     Rect mTaskViewRect = new Rect();
+    int mHeaderBarHeight;
+    int mHeaderButtonPadding;
     int mCornerRadius;
     int mHighlightHeight;
     @ViewDebug.ExportedProperty(category="recents")
@@ -245,6 +249,67 @@
         }
         mFocusTimerIndicatorStub = (ViewStub) findViewById(R.id.focus_timer_indicator_stub);
         mAppOverlayViewStub = (ViewStub) findViewById(R.id.app_overlay_stub);
+
+        onConfigurationChanged();
+    }
+
+    /**
+     * Programmatically sets the layout params for a header bar layout.  This is necessary because
+     * we can't get resources based on the current configuration, but instead need to get them
+     * based on the device configuration.
+     */
+    private void updateLayoutParams(View icon, View title, View secondaryButton, View button) {
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, mHeaderBarHeight, Gravity.TOP);
+        setLayoutParams(lp);
+        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.START);
+        icon.setLayoutParams(lp);
+        lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
+        lp.setMarginStart(mHeaderBarHeight);
+        lp.rightMargin = mMoveTaskButton != null
+                ? 2 * mHeaderBarHeight
+                : mHeaderBarHeight;
+        title.setLayoutParams(lp);
+        if (secondaryButton != null) {
+            lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
+            lp.setMarginEnd(mHeaderBarHeight);
+            secondaryButton.setLayoutParams(lp);
+            secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
+                    mHeaderButtonPadding, mHeaderButtonPadding);
+        }
+        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
+        button.setLayoutParams(lp);
+        button.setPadding(mHeaderButtonPadding, mHeaderButtonPadding, mHeaderButtonPadding,
+                mHeaderButtonPadding);
+    }
+
+    /**
+     * Update the header view when the configuration changes.
+     */
+    void onConfigurationChanged() {
+        // Update the dimensions of everything in the header. We do this because we need to use
+        // resources for the display, and not the current configuration.
+        Resources res = getResources();
+        mHeaderBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height_tablet_land,
+                R.dimen.recents_task_view_header_height,
+                R.dimen.recents_task_view_header_height_tablet_land);
+        mHeaderButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
+                R.dimen.recents_task_view_header_button_padding,
+                R.dimen.recents_task_view_header_button_padding,
+                R.dimen.recents_task_view_header_button_padding,
+                R.dimen.recents_task_view_header_button_padding_tablet_land,
+                R.dimen.recents_task_view_header_button_padding,
+                R.dimen.recents_task_view_header_button_padding_tablet_land);
+        updateLayoutParams(mIconView, findViewById(R.id.title_container), mMoveTaskButton,
+                mDismissButton);
+        if (mAppOverlayView != null) {
+            updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
+        }
     }
 
     @Override
@@ -337,6 +402,11 @@
         }
     }
 
+    /** Only exposed for the workaround for b/27815919. */
+    public ImageView getIconView() {
+        return mIconView;
+    }
+
     /** Returns the secondary color for a primary color. */
     int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) {
         int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK;
@@ -350,6 +420,7 @@
     public void setDimAlpha(float dimAlpha) {
         if (Float.compare(mDimAlpha, dimAlpha) != 0) {
             mDimAlpha = dimAlpha;
+            mTitleView.setAlpha(1f - dimAlpha);
             updateBackgroundColor(mBackground.getColor(), dimAlpha);
         }
     }
@@ -573,6 +644,7 @@
             mAppInfoView = (ImageView) mAppOverlayView.findViewById(R.id.app_info);
             mAppInfoView.setOnClickListener(this);
             mAppTitleView = (TextView) mAppOverlayView.findViewById(R.id.app_title);
+            updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
         }
 
         // Update the overlay contents for the current app
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index e46708e..3eeabc7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -16,7 +16,9 @@
 
 package com.android.systemui.recents.views;
 
+import android.app.ActivityManager;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
@@ -34,6 +36,8 @@
 import android.view.ViewDebug;
 
 import com.android.systemui.R;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.Task;
 
 
@@ -43,17 +47,24 @@
  */
 public class TaskViewThumbnail extends View {
 
-
     private static final ColorMatrix TMP_FILTER_COLOR_MATRIX = new ColorMatrix();
     private static final ColorMatrix TMP_BRIGHTNESS_COLOR_MATRIX = new ColorMatrix();
 
     private Task mTask;
 
+    private Rect mDisplayRect = new Rect();
+    private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
+
     // Drawing
     @ViewDebug.ExportedProperty(category="recents")
+    Rect mTaskViewRect = new Rect();
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mThumbnailRect = new Rect();
     @ViewDebug.ExportedProperty(category="recents")
-    Rect mTaskViewRect = new Rect();
+    float mThumbnailScale;
+    float mFullscreenThumbnailScale;
+    ActivityManager.TaskThumbnailInfo mThumbnailInfo;
+
     int mCornerRadius;
     @ViewDebug.ExportedProperty(category="recents")
     float mDimAlpha;
@@ -97,6 +108,8 @@
         mCornerRadius = getResources().getDimensionPixelSize(
                 R.dimen.recents_task_view_rounded_corners_radius);
         mBgFillPaint.setColor(Color.WHITE);
+        mFullscreenThumbnailScale = context.getResources().getFraction(
+                com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
     }
 
     /**
@@ -114,57 +127,75 @@
     }
 
     @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        mOrientation = ssp.getDisplayOrientation();
+        mDisplayRect = ssp.getDisplayRect();
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         if (mInvisible) {
             return;
         }
 
-        int thumbnailHeight = (int) (((float) mTaskViewRect.width() / mThumbnailRect.width()) *
-                mThumbnailRect.height());
-        if (thumbnailHeight >= mTaskViewRect.height()) {
-            // The thumbnail fills the full task view bounds, so just draw it
-            canvas.drawRoundRect(0, 0, mTaskViewRect.width(), mTaskViewRect.height(),
-                    mCornerRadius, mCornerRadius, mDrawPaint);
-        } else {
-            int count = 0;
-            if (thumbnailHeight > 0) {
-                // The thumbnail only covers part of the task view bounds, so fill in the
-                // non-thumbnail space with the default background color.  This is the equivalent of
-                // the GL border texture mode.
-                count = canvas.save();
+        if (mBitmapShader != null) {
+            int viewWidth = mTaskViewRect.width();
+            int viewHeight = mTaskViewRect.height();
+
+            // We are drawing the thumbnail in the same orientation, so just fit the width
+            int thumbnailWidth = (int) (mThumbnailRect.width() * mThumbnailScale);
+            int thumbnailHeight = (int) (mThumbnailRect.height() * mThumbnailScale);
+
+            if (thumbnailWidth >= viewWidth && thumbnailHeight >= viewHeight) {
+                // Thumbnail fills the full task view bounds, so just draw it
+                canvas.drawRoundRect(0, 0, viewWidth, viewHeight, mCornerRadius, mCornerRadius,
+                        mDrawPaint);
+            } else {
+                // Thumbnail does not fill the full task view bounds, so just draw it and fill the
+                // empty areas with the background color
+                int count = canvas.save();
 
                 // Since we only want the top corners to be rounded, draw slightly beyond the
                 // thumbnail height, but clip to the thumbnail height
-                canvas.clipRect(0, 0, mTaskViewRect.width(), thumbnailHeight, Region.Op.REPLACE);
-                canvas.drawRoundRect(0, 0, mTaskViewRect.width(), thumbnailHeight + mCornerRadius,
+                canvas.clipRect(0, 0, thumbnailWidth, thumbnailHeight, Region.Op.REPLACE);
+                canvas.drawRoundRect(0, 0,
+                        thumbnailWidth + (thumbnailWidth < viewWidth ? mCornerRadius : 0),
+                        thumbnailHeight + (thumbnailHeight < viewHeight ? mCornerRadius : 0),
                         mCornerRadius, mCornerRadius, mDrawPaint);
-            }
 
-            // In the remaining space, draw the background color
-            canvas.clipRect(0, thumbnailHeight, mTaskViewRect.width(), mTaskViewRect.height(),
-                    Region.Op.REPLACE);
-            canvas.drawRoundRect(0, Math.max(0, thumbnailHeight - mCornerRadius),
-                    mTaskViewRect.width(), mTaskViewRect.height(), mCornerRadius, mCornerRadius,
-                    mBgFillPaint);
+                // In the remaining space, draw the background color
+                if (thumbnailWidth < viewWidth) {
+                    canvas.clipRect(thumbnailWidth, 0, viewWidth, viewHeight, Region.Op.REPLACE);
+                    canvas.drawRoundRect(Math.max(0, thumbnailWidth - mCornerRadius), 0,
+                            viewWidth, viewHeight, mCornerRadius, mCornerRadius, mBgFillPaint);
+                }
+                if (thumbnailWidth > 0 && thumbnailHeight < viewHeight) {
+                    canvas.clipRect(0, thumbnailHeight, viewWidth, viewHeight, Region.Op.REPLACE);
+                    canvas.drawRoundRect(0, Math.max(0, thumbnailHeight - mCornerRadius),
+                            viewWidth, viewHeight, mCornerRadius, mCornerRadius, mBgFillPaint);
+                }
 
-            if (thumbnailHeight > 0) {
                 canvas.restoreToCount(count);
             }
         }
     }
 
     /** Sets the thumbnail to a given bitmap. */
-    void setThumbnail(Bitmap bm) {
+    void setThumbnail(Bitmap bm, ActivityManager.TaskThumbnailInfo thumbnailInfo) {
         if (bm != null) {
-            mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP,
-                    Shader.TileMode.CLAMP);
+            mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
             mDrawPaint.setShader(mBitmapShader);
             mThumbnailRect.set(0, 0, bm.getWidth(), bm.getHeight());
+            mThumbnailInfo = thumbnailInfo;
             updateThumbnailScale();
         } else {
             mBitmapShader = null;
             mDrawPaint.setShader(null);
             mThumbnailRect.setEmpty();
+            mThumbnailInfo = null;
         }
     }
 
@@ -210,20 +241,41 @@
      * Updates the scale of the bitmap relative to this view.
      */
     public void updateThumbnailScale() {
+        mThumbnailScale = 1f;
         if (mBitmapShader != null) {
-            float thumbnailScale;
-            if (!mTask.isFreeformTask() || mTask.bounds == null) {
-                // If this is a stack task, or a stack task moved into the freeform workspace, then
-                // just scale this thumbnail to fit the width of the view
-                thumbnailScale = (float) mTaskViewRect.width() / mThumbnailRect.width();
+            // We consider this a stack task if it is not freeform (ie. has no bounds) or has been
+            // dragged into the stack from the freeform workspace
+            boolean isStackTask = !mTask.isFreeformTask() || mTask.bounds == null;
+            if (mTaskViewRect.isEmpty() || mThumbnailInfo == null ||
+                    mThumbnailInfo.taskWidth == 0 || mThumbnailInfo.taskHeight == 0) {
+                // If we haven't measured or the thumbnail is invalid, skip the thumbnail drawing
+                // and only draw the background color
+                mThumbnailScale = 0f;
+            } else if (isStackTask) {
+                float invThumbnailScale = 1f / mFullscreenThumbnailScale;
+                if (mOrientation == Configuration.ORIENTATION_PORTRAIT) {
+                    if (mThumbnailInfo.screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
+                        // If we are in the same orientation as the screenshot, just scale it to the
+                        // width of the task view
+                        mThumbnailScale = (float) mTaskViewRect.width() / mThumbnailRect.width();
+                    } else {
+                        // Scale the landscape thumbnail up to app size, then scale that to the task
+                        // view size to match other portrait screenshots
+                        mThumbnailScale = invThumbnailScale *
+                                ((float) mTaskViewRect.width() / mDisplayRect.width());
+                    }
+                } else {
+                    // Otherwise, scale the screenshot to fit 1:1 in the current orientation
+                    mThumbnailScale = invThumbnailScale;
+                }
             } else {
                 // Otherwise, if this is a freeform task with task bounds, then scale the thumbnail
                 // to fit the entire bitmap into the task bounds
-                thumbnailScale = Math.min(
+                mThumbnailScale = Math.min(
                         (float) mTaskViewRect.width() / mThumbnailRect.width(),
                         (float) mTaskViewRect.height() / mThumbnailRect.height());
             }
-            mScaleMatrix.setScale(thumbnailScale, thumbnailScale);
+            mScaleMatrix.setScale(mThumbnailScale, mThumbnailScale);
             mBitmapShader.setLocalMatrix(mScaleMatrix);
         }
         if (!mInvisible) {
@@ -261,22 +313,23 @@
     }
 
     /** Binds the thumbnail view to the task */
-    void rebindToTask(Task t, boolean disabledInSafeMode) {
+    void rebindToTask(Task t, ActivityManager.TaskThumbnailInfo thumbnailInfo,
+            boolean disabledInSafeMode) {
         mTask = t;
         mDisabledInSafeMode = disabledInSafeMode;
         if (t.thumbnail != null) {
-            setThumbnail(t.thumbnail);
+            setThumbnail(t.thumbnail, thumbnailInfo);
             if (t.colorBackground != 0) {
                 mBgFillPaint.setColor(t.colorBackground);
             }
         } else {
-            setThumbnail(null);
+            setThumbnail(null, null);
         }
     }
 
     /** Unbinds the thumbnail view from the task */
     void unbindFromTask() {
         mTask = null;
-        setThumbnail(null);
+        setThumbnail(null, null);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index dd59fac..e8cf126 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -41,6 +41,7 @@
     private DockDividerVisibilityListener mDockDividerVisibilityListener;
     private boolean mVisible = false;
     private boolean mMinimized = false;
+    private ForcedResizableInfoActivityController mForcedResizableController;
 
     @Override
     public void start() {
@@ -52,6 +53,7 @@
         mDockDividerVisibilityListener = new DockDividerVisibilityListener();
         SystemServicesProxy ssp = Recents.getSystemServices();
         ssp.registerDockedStackListener(mDockDividerVisibilityListener);
+        mForcedResizableController = new ForcedResizableInfoActivityController(mContext);
     }
 
     @Override
@@ -117,6 +119,15 @@
         });
     }
 
+    private void notifyDockedStackExistsChanged(final boolean exists) {
+        mView.post(new Runnable() {
+            @Override
+            public void run() {
+                mForcedResizableController.notifyDockedStackExistsChanged(exists);
+            }
+        });
+    }
+
     class DockDividerVisibilityListener extends IDockedStackListener.Stub {
 
         @Override
@@ -126,6 +137,7 @@
 
         @Override
         public void onDockedStackExistsChanged(boolean exists) throws RemoteException {
+            notifyDockedStackExistsChanged(exists);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 132c09f..7a933cd 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -66,6 +66,8 @@
 import com.android.systemui.recents.events.activity.UndockingTaskEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.stackdivider.events.StartedDragingEvent;
+import com.android.systemui.stackdivider.events.StoppedDragingEvent;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
 
@@ -81,6 +83,7 @@
     private static final String TAG = "DividerView";
 
     private static final int TASK_POSITION_SAME = Integer.MAX_VALUE;
+    private static final boolean SWAPPING_ENABLED = false;
 
     /**
      * How much the background gets scaled when we are in the minimized dock state.
@@ -168,6 +171,13 @@
         }
     };
 
+    private final Runnable mResetBackgroundRunnable = new Runnable() {
+        @Override
+        public void run() {
+            resetBackground();
+        }
+    };
+
     public DividerView(Context context) {
         super(context);
     }
@@ -211,12 +221,14 @@
         mGestureDetector = new GestureDetector(mContext, new SimpleOnGestureListener() {
             @Override
             public boolean onSingleTapUp(MotionEvent e) {
-                updateDockSide();
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                if (mDockSide != WindowManager.DOCKED_INVALID
-                        && !ssp.isRecentsTopMost(ssp.getTopMostTask(), null /* isTopHome */)) {
-                    mWindowManagerProxy.swapTasks();
-                    return true;
+                if (SWAPPING_ENABLED) {
+                    updateDockSide();
+                    SystemServicesProxy ssp = Recents.getSystemServices();
+                    if (mDockSide != WindowManager.DOCKED_INVALID
+                            && !ssp.isRecentsTopMost(ssp.getTopMostTask(), null /* isTopHome */)) {
+                        mWindowManagerProxy.swapTasks();
+                        return true;
+                    }
                 }
                 return false;
             }
@@ -281,6 +293,7 @@
             mWindowManager.setSlippery(false);
             liftBackground();
         }
+        EventBus.getDefault().send(new StartedDragingEvent());
         return mDockSide != WindowManager.DOCKED_INVALID;
     }
 
@@ -380,13 +393,6 @@
                 x = (int) event.getRawX();
                 y = (int) event.getRawY();
 
-                if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
-                    int position = calculatePosition(x, y);
-                    SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(position,
-                            0 /* velocity */, false /* hardDismiss */);
-                    resizeStack(calculatePosition(x, y), snapTarget.position, snapTarget);
-                }
-
                 mVelocityTracker.computeCurrentVelocity(1000);
                 int position = calculatePosition(x, y);
                 stopDragging(position, isHorizontalDivision() ? mVelocityTracker.getYVelocity()
@@ -439,6 +445,7 @@
                 mDockSide = WindowManager.DOCKED_INVALID;
                 mCurrentAnimator = null;
                 mEntranceAnimationRunning = false;
+                EventBus.getDefault().send(new StoppedDragingEvent());
             }
         });
         mCurrentAnimator = anim;
@@ -519,15 +526,17 @@
     public void setMinimizedDockStack(boolean minimized) {
         updateDockSide();
         mHandle.setAlpha(minimized ? 0f : 1f);
-        if (mDockSide == WindowManager.DOCKED_TOP) {
+        if (!minimized) {
+            resetBackground();
+        } else if (mDockSide == WindowManager.DOCKED_TOP) {
             mBackground.setPivotY(0);
-            mBackground.setScaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+            mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
         } else if (mDockSide == WindowManager.DOCKED_LEFT
                 || mDockSide == WindowManager.DOCKED_RIGHT) {
             mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
                     ? 0
                     : mBackground.getWidth());
-            mBackground.setScaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+            mBackground.setScaleX(MINIMIZE_DOCK_SCALE);
         }
     }
 
@@ -550,12 +559,22 @@
             mBackground.animate()
                     .scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
         }
+        if (!minimized) {
+            mBackground.animate().withEndAction(mResetBackgroundRunnable);
+        }
         mBackground.animate()
                 .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .setDuration(animDuration)
                 .start();
     }
 
+    private void resetBackground() {
+        mBackground.setPivotX(mBackground.getWidth() / 2);
+        mBackground.setPivotY(mBackground.getHeight() / 2);
+        mBackground.setScaleX(1f);
+        mBackground.setScaleY(1f);
+    }
+
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
@@ -730,21 +749,22 @@
                 mSnapAlgorithm.calculateDismissingFraction(position)));
         SnapTarget dismissTarget = null;
         SnapTarget splitTarget = null;
-        if ((snapTarget.flag == SnapTarget.FLAG_DISMISS_START
-                || snapTarget == mSnapAlgorithm.getFirstSplitTarget())
+        int start = 0;
+        if (position <= mSnapAlgorithm.getLastSplitTarget().position
                 && dockSideTopLeft(dockSide)) {
             dismissTarget = mSnapAlgorithm.getDismissStartTarget();
             splitTarget = mSnapAlgorithm.getFirstSplitTarget();
-        } else if ((snapTarget.flag == SnapTarget.FLAG_DISMISS_END
-                || snapTarget == mSnapAlgorithm.getLastSplitTarget())
+            start = taskPosition;
+        } else if (position >= mSnapAlgorithm.getLastSplitTarget().position
                 && dockSideBottomRight(dockSide)) {
             dismissTarget = mSnapAlgorithm.getDismissEndTarget();
             splitTarget = mSnapAlgorithm.getLastSplitTarget();
+            start = splitTarget.position;
         }
         if (dismissTarget != null && fraction > 0f
                 && isDismissing(splitTarget, position, dockSide)) {
             fraction = calculateParallaxDismissingFraction(fraction, dockSide);
-            int offsetPosition = (int) (taskPosition +
+            int offsetPosition = (int) (start +
                     fraction * (dismissTarget.position - splitTarget.position));
             int width = taskRect.width();
             int height = taskRect.height();
@@ -792,11 +812,12 @@
     }
 
     private int getStackIdForDismissTarget(SnapTarget dismissTarget) {
-        if (dismissTarget.flag == SnapTarget.FLAG_DISMISS_START &&
-                (mDockSide == WindowManager.DOCKED_LEFT || mDockSide == WindowManager.DOCKED_TOP)) {
+        if ((dismissTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(mDockSide))
+                || (dismissTarget.flag == SnapTarget.FLAG_DISMISS_END
+                        && dockSideBottomRight(mDockSide))) {
             return StackId.DOCKED_STACK_ID;
         } else {
-            return StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+            return StackId.HOME_STACK_ID;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
new file mode 100644
index 0000000..f728dab
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.stackdivider;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+
+import com.android.systemui.R;
+
+/**
+ * Translucent activity that gets started on top of a task in multi-window to inform the user that
+ * we forced the activity below to be resizable.
+ */
+public class ForcedResizableInfoActivity extends Activity implements OnTouchListener {
+
+    private static final long DISMISS_DELAY = 2500;
+
+    private final Runnable mFinishRunnable = new Runnable() {
+        @Override
+        public void run() {
+            finish();
+        }
+    };
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.forced_resizable_activity);
+        getWindow().getDecorView().setOnTouchListener(this);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        getWindow().getDecorView().postDelayed(mFinishRunnable, DISMISS_DELAY);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        finish();
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        finish();
+        return true;
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        finish();
+        return true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
new file mode 100644
index 0000000..9b56037
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.stackdivider;
+
+import android.app.ActivityOptions;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
+import com.android.systemui.recents.events.activity.ForcedResizableEvent;
+import com.android.systemui.stackdivider.events.StartedDragingEvent;
+import com.android.systemui.stackdivider.events.StoppedDragingEvent;
+
+/**
+ * Controller that decides when to show the {@link ForcedResizableInfoActivity}.
+ */
+public class ForcedResizableInfoActivityController {
+
+    private static final String SELF_PACKAGE_NAME = "com.android.systemui";
+
+    private static final int TIMEOUT = 1000;
+    private final Context mContext;
+    private final Handler mHandler = new Handler();
+    private final ArraySet<Integer> mPendingTaskIds = new ArraySet<>();
+    private final ArraySet<String> mPackagesShownInSession = new ArraySet<>();
+    private boolean mDividerDraging;
+
+    private final Runnable mTimeoutRunnable = new Runnable() {
+        @Override
+        public void run() {
+            showPending();
+        }
+    };
+
+    public ForcedResizableInfoActivityController(Context context) {
+        mContext = context;
+        EventBus.getDefault().register(this);
+    }
+
+    public void notifyDockedStackExistsChanged(boolean exists) {
+        if (!exists) {
+            mPackagesShownInSession.clear();
+        }
+    }
+
+    public final void onBusEvent(ForcedResizableEvent forcedResizableEvent) {
+        if (debounce(forcedResizableEvent.packageName)) {
+            return;
+        }
+        mPendingTaskIds.add(forcedResizableEvent.taskId);
+        postTimeout();
+    }
+
+    public final void onBusEvent(AppTransitionFinishedEvent event) {
+        if (!mDividerDraging) {
+            showPending();
+        }
+    }
+
+    public final void onBusEvent(StartedDragingEvent event) {
+        mDividerDraging = true;
+        mHandler.removeCallbacks(mTimeoutRunnable);
+    }
+
+    public final void onBusEvent(StoppedDragingEvent event) {
+        mDividerDraging = false;
+        showPending();
+    }
+
+    private void showPending() {
+        mHandler.removeCallbacks(mTimeoutRunnable);
+        for (int i = mPendingTaskIds.size() - 1; i >= 0; i--) {
+            Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class);
+            ActivityOptions options = ActivityOptions.makeBasic();
+            options.setLaunchTaskId(mPendingTaskIds.valueAt(i));
+            mContext.startActivity(intent, options.toBundle());
+        }
+        mPendingTaskIds.clear();
+    }
+
+    private void postTimeout() {
+        mHandler.removeCallbacks(mTimeoutRunnable);
+        mHandler.postDelayed(mTimeoutRunnable, TIMEOUT);
+    }
+
+    private boolean debounce(String packageName) {
+        if (packageName == null) {
+            return false;
+        }
+
+        // We launch ForcedResizableInfoActivity into a task that was forced resizable, so that
+        // triggers another notification. So ignore our own activity.
+        if (SELF_PACKAGE_NAME.equals(packageName)) {
+            return true;
+        }
+        boolean debounce = mPackagesShownInSession.contains(packageName);
+        mPackagesShownInSession.add(packageName);
+        return debounce;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java
similarity index 74%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
copy to packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java
index 98c0a69..5d19851 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java
@@ -11,16 +11,15 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
 
-package com.android.systemui.recents.events.activity;
+package com.android.systemui.stackdivider.events;
 
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the history is to be cleared
+ * Sent when the divider is being draged either manually or by an animation.
  */
-public class ClearHistoryEvent extends EventBus.AnimatedEvent {
-    // Simple event
+public class StartedDragingEvent extends EventBus.Event {
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java
similarity index 74%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
copy to packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java
index 98c0a69..c50d6d6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ClearHistoryEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java
@@ -11,16 +11,15 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
 
-package com.android.systemui.recents.events.activity;
+package com.android.systemui.stackdivider.events;
 
 import com.android.systemui.recents.events.EventBus;
 
 /**
- * This is sent when the history is to be cleared
+ * Sent when the divider isn't draging anymore.
  */
-public class ClearHistoryEvent extends EventBus.AnimatedEvent {
-    // Simple event
+public class StoppedDragingEvent extends EventBus.Event {
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 2d2a08a..1c5d28a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1206,10 +1206,10 @@
     }
 
     @Override
-    public void toggleKeyboardShortcutsMenu() {
+    public void toggleKeyboardShortcutsMenu(int deviceId) {
         int msg = MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU;
         mHandler.removeMessages(msg);
-        mHandler.sendEmptyMessage(msg);
+        mHandler.obtainMessage(msg, deviceId, 0).sendToTarget();
     }
 
     /** Jumps to the next affiliated task in the group. */
@@ -1295,8 +1295,8 @@
         }
     }
 
-    protected void toggleKeyboardShortcuts() {
-        getKeyboardShortcuts().toggleKeyboardShortcuts();
+    protected void toggleKeyboardShortcuts(int deviceId) {
+        getKeyboardShortcuts().toggleKeyboardShortcuts(deviceId);
     }
 
     protected void cancelPreloadingRecents() {
@@ -1469,7 +1469,7 @@
                   showRecentsPreviousAffiliatedTask();
                   break;
              case MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU:
-                  toggleKeyboardShortcuts();
+                  toggleKeyboardShortcuts(m.arg1);
                   break;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 6a98488..99b6397 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -73,6 +73,7 @@
     private static final int MSG_REMOVE_QS_TILE                = 28 << MSG_SHIFT;
     private static final int MSG_CLICK_QS_TILE                 = 29 << MSG_SHIFT;
     private static final int MSG_TOGGLE_APP_SPLIT_SCREEN       = 30 << MSG_SHIFT;
+    private static final int MSG_APP_TRANSITION_FINISHED       = 31 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -91,36 +92,37 @@
      * These methods are called back on the main thread.
      */
     public interface Callbacks {
-        public void setIcon(String slot, StatusBarIcon icon);
-        public void removeIcon(String slot);
-        public void disable(int state1, int state2, boolean animate);
-        public void animateExpandNotificationsPanel();
-        public void animateCollapsePanels(int flags);
-        public void animateExpandSettingsPanel(String obj);
-        public void setSystemUiVisibility(int vis, int fullscreenStackVis,
+        void setIcon(String slot, StatusBarIcon icon);
+        void removeIcon(String slot);
+        void disable(int state1, int state2, boolean animate);
+        void animateExpandNotificationsPanel();
+        void animateCollapsePanels(int flags);
+        void animateExpandSettingsPanel(String obj);
+        void setSystemUiVisibility(int vis, int fullscreenStackVis,
                 int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds);
-        public void topAppWindowChanged(boolean visible);
-        public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
+        void topAppWindowChanged(boolean visible);
+        void setImeWindowStatus(IBinder token, int vis, int backDisposition,
                 boolean showImeSwitcher);
-        public void showRecentApps(boolean triggeredFromAltTab);
-        public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
-        public void toggleRecentApps();
-        public void toggleSplitScreen();
-        public void preloadRecentApps();
-        public void toggleKeyboardShortcutsMenu();
-        public void cancelPreloadRecentApps();
-        public void setWindowState(int window, int state);
-        public void buzzBeepBlinked();
-        public void notificationLightOff();
-        public void notificationLightPulse(int argb, int onMillis, int offMillis);
-        public void showScreenPinningRequest();
-        public void appTransitionPending();
-        public void appTransitionCancelled();
-        public void appTransitionStarting(long startTime, long duration);
-        public void showAssistDisclosure();
-        public void startAssist(Bundle args);
-        public void onCameraLaunchGestureDetected(int source);
-        public void requestTvPictureInPicture();
+        void showRecentApps(boolean triggeredFromAltTab);
+        void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
+        void toggleRecentApps();
+        void toggleSplitScreen();
+        void preloadRecentApps();
+        void toggleKeyboardShortcutsMenu(int deviceId);
+        void cancelPreloadRecentApps();
+        void setWindowState(int window, int state);
+        void buzzBeepBlinked();
+        void notificationLightOff();
+        void notificationLightPulse(int argb, int onMillis, int offMillis);
+        void showScreenPinningRequest();
+        void appTransitionPending();
+        void appTransitionCancelled();
+        void appTransitionStarting(long startTime, long duration);
+        void appTransitionFinished();
+        void showAssistDisclosure();
+        void startAssist(Bundle args);
+        void onCameraLaunchGestureDetected(int source);
+        void requestTvPictureInPicture();
 
         void addQsTile(ComponentName tile);
         void remQsTile(ComponentName tile);
@@ -254,10 +256,10 @@
     }
 
     @Override
-    public void toggleKeyboardShortcutsMenu() {
+    public void toggleKeyboardShortcutsMenu(int deviceId) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS);
-            mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS).sendToTarget();
+            mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget();
         }
     }
 
@@ -324,6 +326,14 @@
         }
     }
 
+    @Override
+    public void appTransitionFinished() {
+        synchronized (mLock) {
+            mHandler.removeMessages(MSG_APP_TRANSITION_FINISHED);
+            mHandler.sendEmptyMessage(MSG_APP_TRANSITION_FINISHED);
+        }
+    }
+
     public void showAssistDisclosure() {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_ASSIST_DISCLOSURE);
@@ -425,7 +435,7 @@
                     mCallbacks.cancelPreloadRecentApps();
                     break;
                 case MSG_TOGGLE_KEYBOARD_SHORTCUTS:
-                    mCallbacks.toggleKeyboardShortcutsMenu();
+                    mCallbacks.toggleKeyboardShortcutsMenu(msg.arg1);
                     break;
                 case MSG_SET_WINDOW_STATE:
                     mCallbacks.setWindowState(msg.arg1, msg.arg2);
@@ -452,6 +462,9 @@
                     Pair<Long, Long> data = (Pair<Long, Long>) msg.obj;
                     mCallbacks.appTransitionStarting(data.first, data.second);
                     break;
+                case MSG_APP_TRANSITION_FINISHED:
+                    mCallbacks.appTransitionFinished();
+                    break;
                 case MSG_ASSIST_DISCLOSURE:
                     mCallbacks.showAssistDisclosure();
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 60c2fa6..8fe60a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -21,9 +21,14 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
+import android.hardware.input.InputManager;
 import android.os.Handler;
 import android.os.Looper;
+import android.util.Log;
+import android.util.SparseArray;
 import android.view.ContextThemeWrapper;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
@@ -42,16 +47,163 @@
 import java.util.List;
 
 import static android.content.Context.LAYOUT_INFLATER_SERVICE;
-import static android.view.Gravity.TOP;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 
 /**
  * Contains functionality for handling keyboard shortcuts.
  */
 public class KeyboardShortcuts {
-    private static final char SYSTEM_HOME_BASE_CHARACTER = '\u2386';
-    private static final char SYSTEM_BACK_BASE_CHARACTER = '\u007F';
-    private static final char SYSTEM_RECENTS_BASE_CHARACTER = '\u0009';
+    private static final String TAG = KeyboardShortcuts.class.getSimpleName();
+
+    private static final SparseArray<String> SPECIAL_CHARACTER_NAMES = new SparseArray<>();
+    private static final SparseArray<String> MODIFIER_NAMES = new SparseArray<>();
+
+    private static void loadSpecialCharacterNames(Context context) {
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_HOME, context.getString(R.string.keyboard_key_home));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_BACK, context.getString(R.string.keyboard_key_back));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_DPAD_UP, context.getString(R.string.keyboard_key_dpad_up));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_DPAD_DOWN, context.getString(R.string.keyboard_key_dpad_down));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_DPAD_LEFT, context.getString(R.string.keyboard_key_dpad_left));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_DPAD_RIGHT, context.getString(R.string.keyboard_key_dpad_right));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_DPAD_CENTER, context.getString(R.string.keyboard_key_dpad_center));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_PERIOD, ".");
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_TAB, context.getString(R.string.keyboard_key_tab));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_SPACE, context.getString(R.string.keyboard_key_space));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_ENTER, context.getString(R.string.keyboard_key_enter));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_DEL, context.getString(R.string.keyboard_key_backspace));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE,
+                context.getString(R.string.keyboard_key_media_play_pause));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_MEDIA_STOP, context.getString(R.string.keyboard_key_media_stop));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_MEDIA_NEXT, context.getString(R.string.keyboard_key_media_next));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_PREVIOUS,
+                context.getString(R.string.keyboard_key_media_previous));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_REWIND,
+                context.getString(R.string.keyboard_key_media_rewind));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD,
+                context.getString(R.string.keyboard_key_media_fast_forward));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_PAGE_UP, context.getString(R.string.keyboard_key_page_up));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_PAGE_DOWN, context.getString(R.string.keyboard_key_page_down));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_A,
+                context.getString(R.string.keyboard_key_button_template, "A"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_B,
+                context.getString(R.string.keyboard_key_button_template, "B"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_C,
+                context.getString(R.string.keyboard_key_button_template, "C"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_X,
+                context.getString(R.string.keyboard_key_button_template, "X"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_Y,
+                context.getString(R.string.keyboard_key_button_template, "Y"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_Z,
+                context.getString(R.string.keyboard_key_button_template, "Z"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_L1,
+                context.getString(R.string.keyboard_key_button_template, "L1"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_R1,
+                context.getString(R.string.keyboard_key_button_template, "R1"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_L2,
+                context.getString(R.string.keyboard_key_button_template, "L2"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_R2,
+                context.getString(R.string.keyboard_key_button_template, "R2"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_START,
+                context.getString(R.string.keyboard_key_button_template, "Start"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_SELECT,
+                context.getString(R.string.keyboard_key_button_template, "Select"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_MODE,
+                context.getString(R.string.keyboard_key_button_template, "Mode"));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_FORWARD_DEL, context.getString(R.string.keyboard_key_forward_del));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_ESCAPE, "Esc");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_SYSRQ, "SysRq");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BREAK, "Break");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_SCROLL_LOCK, "Scroll Lock");
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_MOVE_HOME, context.getString(R.string.keyboard_key_move_home));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_MOVE_END, context.getString(R.string.keyboard_key_move_end));
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_INSERT, context.getString(R.string.keyboard_key_insert));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F1, "F1");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F2, "F2");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F3, "F3");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F4, "F4");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F5, "F5");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F6, "F6");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F7, "F7");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F8, "F8");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F9, "F9");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F10, "F10");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F11, "F11");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F12, "F12");
+        SPECIAL_CHARACTER_NAMES.put(
+                KeyEvent.KEYCODE_NUM_LOCK, context.getString(R.string.keyboard_key_num_lock));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_0,
+                context.getString(R.string.keyboard_key_numpad_template, "0"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_1,
+                context.getString(R.string.keyboard_key_numpad_template, "1"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_2,
+                context.getString(R.string.keyboard_key_numpad_template, "2"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_3,
+                context.getString(R.string.keyboard_key_numpad_template, "3"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_4,
+                context.getString(R.string.keyboard_key_numpad_template, "4"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_5,
+                context.getString(R.string.keyboard_key_numpad_template, "5"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_6,
+                context.getString(R.string.keyboard_key_numpad_template, "6"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_7,
+                context.getString(R.string.keyboard_key_numpad_template, "7"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_8,
+                context.getString(R.string.keyboard_key_numpad_template, "8"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_9,
+                context.getString(R.string.keyboard_key_numpad_template, "9"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_DIVIDE,
+                context.getString(R.string.keyboard_key_numpad_template, "/"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_MULTIPLY,
+                context.getString(R.string.keyboard_key_numpad_template, "*"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_SUBTRACT,
+                context.getString(R.string.keyboard_key_numpad_template, "-"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_ADD,
+                context.getString(R.string.keyboard_key_numpad_template, "+"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_DOT,
+                context.getString(R.string.keyboard_key_numpad_template, "."));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_COMMA,
+                context.getString(R.string.keyboard_key_numpad_template, ","));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_ENTER,
+                context.getString(R.string.keyboard_key_numpad_template,
+                        context.getString(R.string.keyboard_key_enter)));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_EQUALS,
+                context.getString(R.string.keyboard_key_numpad_template, "="));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN,
+                context.getString(R.string.keyboard_key_numpad_template, "("));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN,
+                context.getString(R.string.keyboard_key_numpad_template, ")"));
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_ZENKAKU_HANKAKU, "半角/全角");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_EISU, "英数");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MUHENKAN, "無変換");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_HENKAN, "変換");
+        SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな");
+
+        MODIFIER_NAMES.put(KeyEvent.META_META_ON, "Meta");
+        MODIFIER_NAMES.put(KeyEvent.META_CTRL_ON, "Ctrl");
+        MODIFIER_NAMES.put(KeyEvent.META_ALT_ON, "Alt");
+        MODIFIER_NAMES.put(KeyEvent.META_SHIFT_ON, "Shift");
+        MODIFIER_NAMES.put(KeyEvent.META_SYM_ON, "Sym");
+        MODIFIER_NAMES.put(KeyEvent.META_FUNCTION_ON, "Fn");
+    }
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Context mContext;
@@ -62,12 +214,20 @@
     };
 
     private Dialog mKeyboardShortcutsDialog;
+    private KeyCharacterMap mKeyCharacterMap;
 
     public KeyboardShortcuts(Context context) {
         this.mContext = new ContextThemeWrapper(context, android.R.style.Theme_Material_Light);
+        if (SPECIAL_CHARACTER_NAMES.size() == 0) {
+            loadSpecialCharacterNames(context);
+        }
     }
 
-    public void toggleKeyboardShortcuts() {
+    public void toggleKeyboardShortcuts(int deviceId) {
+        InputDevice inputDevice = InputManager.getInstance().getInputDevice(deviceId);
+        if (inputDevice != null) {
+            mKeyCharacterMap = inputDevice.getKeyCharacterMap();
+        }
         if (mKeyboardShortcutsDialog == null) {
             Recents.getSystemServices().requestKeyboardShortcuts(mContext,
                 new KeyboardShortcutsReceiver() {
@@ -75,20 +235,20 @@
                     public void onKeyboardShortcutsReceived(
                             final List<KeyboardShortcutGroup> result) {
                         KeyboardShortcutGroup systemGroup = new KeyboardShortcutGroup(
-                            mContext.getString(R.string.keyboard_shortcut_group_system), true);
+                                mContext.getString(R.string.keyboard_shortcut_group_system), true);
                         systemGroup.addItem(new KeyboardShortcutInfo(
-                            mContext.getString(R.string.keyboard_shortcut_group_system_home),
-                            SYSTEM_HOME_BASE_CHARACTER, KeyEvent.META_META_ON));
+                                mContext.getString(R.string.keyboard_shortcut_group_system_home),
+                                KeyEvent.KEYCODE_ENTER, KeyEvent.META_META_ON));
                         systemGroup.addItem(new KeyboardShortcutInfo(
-                            mContext.getString(R.string.keyboard_shortcut_group_system_back),
-                            SYSTEM_BACK_BASE_CHARACTER, KeyEvent.META_META_ON));
+                                mContext.getString(R.string.keyboard_shortcut_group_system_back),
+                                KeyEvent.KEYCODE_DEL, KeyEvent.META_META_ON));
                         systemGroup.addItem(new KeyboardShortcutInfo(
-                            mContext.getString(R.string.keyboard_shortcut_group_system_recents),
-                            SYSTEM_RECENTS_BASE_CHARACTER, KeyEvent.META_ALT_ON));
+                                mContext.getString(R.string.keyboard_shortcut_group_system_recents),
+                                KeyEvent.KEYCODE_TAB, KeyEvent.META_ALT_ON));
                         result.add(systemGroup);
                         showKeyboardShortcutsDialog(result);
                     }
-                });
+                }, deviceId);
         } else {
             dismissKeyboardShortcutsDialog();
         }
@@ -148,6 +308,18 @@
             final int itemsSize = group.getItems().size();
             for (int j = 0; j < itemsSize; j++) {
                 KeyboardShortcutInfo info = group.getItems().get(j);
+                if (info.getKeycode() != KeyEvent.KEYCODE_UNKNOWN
+                        && !KeyCharacterMap.deviceHasKey(info.getKeycode())) {
+                    // The user can't achieve this shortcut, so skipping.
+                    Log.w(TAG, "Keyboard Shortcut contains key not on device, skipping.");
+                    continue;
+                }
+                List<String> shortcutKeys = getHumanReadableShortcutKeys(info);
+                if (shortcutKeys == null) {
+                    // Ignore shortcuts we can't display keys for.
+                    Log.w(TAG, "Keyboard Shortcut contains unsupported keys, skipping.");
+                    continue;
+                }
                 View shortcutView = inflater.inflate(R.layout.keyboard_shortcut_app_item,
                         shortcutContainer, false);
                 TextView textView = (TextView) shortcutView
@@ -156,7 +328,6 @@
 
                 ViewGroup shortcutItemsContainer = (ViewGroup) shortcutView
                         .findViewById(R.id.keyboard_shortcuts_item_container);
-                List<String> shortcutKeys = getHumanReadableShortcutKeys(info);
                 final int shortcutKeysSize = shortcutKeys.size();
                 for (int k = 0; k < shortcutKeysSize; k++) {
                     String shortcutKey = shortcutKeys.get(k);
@@ -178,11 +349,46 @@
     }
 
     private List<String> getHumanReadableShortcutKeys(KeyboardShortcutInfo info) {
-        // TODO: fix the shortcuts. Find or build an util which can produce human readable
-        // names of the baseCharacter and the modifiers.
-        List<String> shortcutKeys = new ArrayList<>();
-        shortcutKeys.add(KeyEvent.metaStateToString(info.getModifiers()).toUpperCase());
-        shortcutKeys.add(Character.getName(info.getBaseCharacter()).toUpperCase());
+        List<String> shortcutKeys = getHumanReadableModifiers(info);
+        if (shortcutKeys == null) {
+            return null;
+        }
+        String displayLabelString;
+        if (info.getKeycode() == KeyEvent.KEYCODE_UNKNOWN) {
+            displayLabelString = String.valueOf(info.getBaseCharacter());
+        } else if (SPECIAL_CHARACTER_NAMES.get(info.getKeycode()) != null) {
+            displayLabelString = SPECIAL_CHARACTER_NAMES.get(info.getKeycode());
+        } else {
+            // TODO: Have a generic map for when we don't have the device's.
+            char displayLabel = mKeyCharacterMap == null
+                    ? 0 : mKeyCharacterMap.getDisplayLabel(info.getKeycode());
+            if (displayLabel != 0) {
+                displayLabelString = String.valueOf(displayLabel);
+            } else {
+                return null;
+            }
+        }
+        shortcutKeys.add(displayLabelString.toUpperCase());
+        return shortcutKeys;
+    }
+
+    private List<String> getHumanReadableModifiers(KeyboardShortcutInfo info) {
+        final List<String> shortcutKeys = new ArrayList<>();
+        int modifiers = info.getModifiers();
+        if (modifiers == 0) {
+            return shortcutKeys;
+        }
+        for(int i = 0; i < MODIFIER_NAMES.size(); ++i) {
+            final int supportedModifier = MODIFIER_NAMES.keyAt(i);
+            if ((modifiers & supportedModifier) != 0) {
+                shortcutKeys.add(MODIFIER_NAMES.get(supportedModifier).toUpperCase());
+                modifiers &= ~supportedModifier;
+            }
+        }
+        if (modifiers != 0) {
+            // Remaining unsupported modifiers, don't show anything.
+            return null;
+        }
         return shortcutKeys;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index c32ef0e9..4add3cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.car;
 
 import android.app.ActivityManager;
-import android.app.ITaskStackListener;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -25,6 +24,7 @@
 import android.graphics.PixelFormat;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.RemoteException;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewStub;
@@ -33,6 +33,7 @@
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
@@ -40,9 +41,7 @@
  * A status bar (and navigation bar) tailored for the automotive use case.
  */
 public class CarStatusBar extends PhoneStatusBar {
-    private SystemServicesProxy mSystemServicesProxy;
     private TaskStackListenerImpl mTaskStackListener;
-    private Handler mHandler;
 
     private CarNavigationBarView mCarNavigationBar;
     private CarNavigationBarController mController;
@@ -51,10 +50,8 @@
     @Override
     public void start() {
         super.start();
-        mHandler = new Handler();
-        mTaskStackListener = new TaskStackListenerImpl(mHandler);
-        mSystemServicesProxy = new SystemServicesProxy(mContext);
-        mSystemServicesProxy.registerTaskStackListener(mTaskStackListener);
+        mTaskStackListener = new TaskStackListenerImpl();
+        SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
         registerPackageChangeReceivers();
     }
 
@@ -114,47 +111,16 @@
     }
 
     /**
-     * An implementation of ITaskStackListener, that listens for changes in the system task
+     * An implementation of TaskStackListener, that listens for changes in the system task
      * stack and notifies the navigation bar.
      */
-    private class TaskStackListenerImpl extends ITaskStackListener.Stub implements Runnable {
-        private Handler mHandler;
-
-        public TaskStackListenerImpl(Handler handler) {
-            this.mHandler = handler;
-        }
-
-        @Override
-        public void onActivityPinned() {
-        }
-
-        @Override
-        public void onPinnedActivityRestartAttempt() {
-        }
-
-        @Override
-        public void onPinnedStackAnimationEnded() {
-        }
-
+    private class TaskStackListenerImpl extends TaskStackListener {
         @Override
         public void onTaskStackChanged() {
-            mHandler.removeCallbacks(this);
-            mHandler.post(this);
-        }
-
-        @Override
-        public void run() {
-            ensureMainThread();
             SystemServicesProxy ssp = Recents.getSystemServices();
             ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getTopMostTask();
             mController.taskChanged(runningTaskInfo.baseActivity.getPackageName());
         }
-
-        private void ensureMainThread() {
-            if (!Looper.getMainLooper().isCurrentThread()) {
-                throw new RuntimeException("Must be called on the UI thread");
-            }
-        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index 50ead3d..225751a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.LinearLayout;
@@ -27,14 +28,17 @@
     private static final String TAG = "IconMerger";
     private static final boolean DEBUG = false;
 
-    private int mIconSize;
+    private final int mIconSize;
+    private final int mIconHPadding;
+
     private View mMoreView;
 
     public IconMerger(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        mIconSize = context.getResources().getDimensionPixelSize(
-                R.dimen.status_bar_icon_size);
+        Resources res = context.getResources();
+        mIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+        mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
 
         if (DEBUG) {
             setBackgroundColor(0x800099FF);
@@ -45,12 +49,16 @@
         mMoreView = v;
     }
 
+    private int getFullIconWidth() {
+        return mIconSize + 2 * mIconHPadding;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         // we need to constrain this to an integral multiple of our children
         int width = getMeasuredWidth();
-        setMeasuredDimension(width - (width % mIconSize), getMeasuredHeight());
+        setMeasuredDimension(width - (width % getFullIconWidth()), getMeasuredHeight());
     }
 
     @Override
@@ -70,7 +78,7 @@
         final boolean overflowShown = (mMoreView.getVisibility() == View.VISIBLE);
         // let's assume we have one more slot if the more icon is already showing
         if (overflowShown) visibleChildren --;
-        final boolean moreRequired = visibleChildren * mIconSize > width;
+        final boolean moreRequired = visibleChildren * getFullIconWidth() > width;
         if (moreRequired != overflowShown) {
             post(new Runnable() {
                 @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index a605a81..c4917a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -17,6 +17,7 @@
 import com.android.systemui.statusbar.notification.NotificationUtils;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * A controller for the space in the status bar to the left of the system icons. This area is
@@ -42,6 +43,10 @@
         initializeNotificationAreaViews(context);
     }
 
+    protected View inflateIconArea(LayoutInflater inflater) {
+        return inflater.inflate(R.layout.notification_icon_area, null);
+    }
+
     /**
      * Initializes the views that will represent the notification area.
      */
@@ -51,14 +56,16 @@
         mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
 
         LayoutInflater layoutInflater = LayoutInflater.from(context);
-        mNotificationIconArea = layoutInflater.inflate(R.layout.notification_icon_area, null);
-
-        mMoreIcon = (ImageView) mNotificationIconArea.findViewById(R.id.moreIcon);
-        mMoreIcon.setImageTintList(ColorStateList.valueOf(mIconTint));
+        mNotificationIconArea = inflateIconArea(layoutInflater);
 
         mNotificationIcons =
                 (IconMerger) mNotificationIconArea.findViewById(R.id.notificationIcons);
-        mNotificationIcons.setOverflowIndicator(mMoreIcon);
+
+        mMoreIcon = (ImageView) mNotificationIconArea.findViewById(R.id.moreIcon);
+        if (mMoreIcon != null) {
+            mMoreIcon.setImageTintList(ColorStateList.valueOf(mIconTint));
+            mNotificationIcons.setOverflowIndicator(mMoreIcon);
+        }
     }
 
     /**
@@ -88,16 +95,38 @@
      */
     public void setIconTint(int iconTint) {
         mIconTint = iconTint;
-        mMoreIcon.setImageTintList(ColorStateList.valueOf(mIconTint));
+        if (mMoreIcon != null) {
+            mMoreIcon.setImageTintList(ColorStateList.valueOf(mIconTint));
+        }
         applyNotificationIconsTint();
     }
 
+    protected int getHeight() {
+        return mPhoneStatusBar.getStatusBarHeight();
+    }
+
+    protected boolean shouldShowNotification(NotificationData.Entry entry,
+            NotificationData notificationData) {
+        if (notificationData.isAmbient(entry.key)
+                && !NotificationData.showNotificationEvenIfUnprovisioned(entry.notification)) {
+            return false;
+        }
+        if (!PhoneStatusBar.isTopLevelChild(entry)) {
+            return false;
+        }
+        if (entry.row.getVisibility() == View.GONE) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * Updates the notifications with the given list of notifications to display.
      */
     public void updateNotificationIcons(NotificationData notificationData) {
         final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
-                mIconSize + 2 * mIconHPadding, mPhoneStatusBar.getStatusBarHeight());
+                mIconSize + 2 * mIconHPadding, getHeight());
 
         ArrayList<NotificationData.Entry> activeNotifications =
                 notificationData.getActiveNotifications();
@@ -107,17 +136,9 @@
         // Filter out ambient notifications and notification children.
         for (int i = 0; i < size; i++) {
             NotificationData.Entry ent = activeNotifications.get(i);
-            if (notificationData.isAmbient(ent.key)
-                    && !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
-                continue;
+            if (shouldShowNotification(ent, notificationData)) {
+                toShow.add(ent.icon);
             }
-            if (!PhoneStatusBar.isTopLevelChild(ent)) {
-                continue;
-            }
-            if (ent.row.getVisibility() == View.GONE) {
-                continue;
-            }
-            toShow.add(ent.icon);
         }
 
         ArrayList<View> toRemove = new ArrayList<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index e5e3caf..12035b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -136,7 +136,7 @@
     private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionFromOverscroll;
     private float mLastOverscroll;
-    private boolean mQsExpansionEnabled = true;
+    protected boolean mQsExpansionEnabled = true;
     private ValueAnimator mQsExpansionAnimator;
     private FlingAnimationUtils mFlingAnimationUtils;
     private int mStatusBarMinHeight;
@@ -202,6 +202,7 @@
             notifyBarPanelExpansionChanged();
         }
     };
+    private NotificationGroupManager mGroupManager;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -415,6 +416,11 @@
             if (!(child instanceof ExpandableNotificationRow)) {
                 continue;
             }
+            boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
+                    ((ExpandableNotificationRow) child).getStatusBarNotification());
+            if (suppressedSummary) {
+                continue;
+            }
             availableSpace -= child.getMinHeight() + notificationPadding;
             if (availableSpace >= 0 && count < maximum) {
                 count++;
@@ -1202,7 +1208,9 @@
     }
 
     private String getKeyguardOrLockScreenString() {
-        if (mStatusBarState == StatusBarState.KEYGUARD) {
+        if (mQsContainer.isCustomizing()) {
+            return getContext().getString(R.string.accessibility_desc_quick_settings_edit);
+        } else if (mStatusBarState == StatusBarState.KEYGUARD) {
             return getContext().getString(R.string.accessibility_desc_lock_screen);
         } else {
             return getContext().getString(R.string.accessibility_desc_notification_shade);
@@ -1731,7 +1739,7 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        mNavigationBarBottomHeight = insets.getSystemWindowInsetBottom();
+        mNavigationBarBottomHeight = insets.getStableInsetBottom();
         updateMaxHeadsUpTranslation();
         return insets;
     }
@@ -2298,4 +2306,8 @@
         List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
         return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName());
     }
+
+    public void setGroupManager(NotificationGroupManager groupManager) {
+        mGroupManager = groupManager;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index f0df706..960515b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -75,7 +75,7 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
+        setPadding(0, 0, 0, insets.getStableInsetBottom());
         return insets;
     }
 
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 e84d8fc..bb77c5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -48,7 +48,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
 import android.inputmethodservice.InputMethodService;
 import android.media.AudioAttributes;
 import android.media.MediaMetadata;
@@ -121,6 +120,7 @@
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
 import com.android.systemui.recents.events.activity.UndockingTaskEvent;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.WindowManagerProxy;
@@ -132,7 +132,6 @@
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
-import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
@@ -285,7 +284,7 @@
     HotspotControllerImpl mHotspotController;
     RotationLockControllerImpl mRotationLockController;
     UserInfoController mUserInfoController;
-    ZenModeController mZenModeController;
+    protected ZenModeController mZenModeController;
     CastControllerImpl mCastController;
     VolumeComponent mVolumeComponent;
     KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -305,7 +304,7 @@
     Point mCurrentDisplaySize = new Point();
 
     protected StatusBarWindowView mStatusBarWindow;
-    PhoneStatusBarView mStatusBarView;
+    protected PhoneStatusBarView mStatusBarView;
     private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
     protected StatusBarWindowManager mStatusBarWindowManager;
     private UnlockMethodCache mUnlockMethodCache;
@@ -317,7 +316,7 @@
     int mPixelFormat;
     Object mQueueLock = new Object();
 
-    StatusBarIconController mIconController;
+    protected StatusBarIconController mIconController;
 
     // expanded notifications
     protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -329,7 +328,7 @@
 
     // top bar
     BaseStatusBarHeader mHeader;
-    KeyguardStatusBarView mKeyguardStatusBar;
+    protected KeyguardStatusBarView mKeyguardStatusBar;
     View mKeyguardStatusView;
     KeyguardBottomAreaView mKeyguardBottomArea;
     boolean mLeaveOpenOnKeyguardHide;
@@ -678,6 +677,11 @@
         mFalsingManager = FalsingManager.getInstance(mContext);
     }
 
+    protected void createIconController() {
+        mIconController = new StatusBarIconController(
+                mContext, mStatusBarView, mKeyguardStatusBar, this);
+    }
+
     // ================================================================================
     // Constructing the view
     // ================================================================================
@@ -705,6 +709,7 @@
         mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
                 R.id.notification_panel);
         mNotificationPanel.setStatusBar(this);
+        mNotificationPanel.setGroupManager(mGroupManager);
 
         mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
         mStatusBarView.setBar(this);
@@ -811,8 +816,7 @@
         // set the initial view visibility
         setAreThereNotifications();
 
-        mIconController = new StatusBarIconController(
-                mContext, mStatusBarView, mKeyguardStatusBar, this);
+        createIconController();
 
         // Background thread for any controllers that need it.
         mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
@@ -1989,7 +1993,7 @@
         }
     }
 
-    private int adjustDisableFlags(int state) {
+    protected int adjustDisableFlags(int state) {
         if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway
                 && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
             state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS;
@@ -4307,6 +4311,7 @@
     @Override
     public void appTransitionCancelled() {
         mIconController.appTransitionCancelled();
+        EventBus.getDefault().send(new AppTransitionFinishedEvent());
     }
 
     @Override
@@ -4323,6 +4328,11 @@
     }
 
     @Override
+    public void appTransitionFinished() {
+        EventBus.getDefault().send(new AppTransitionFinishedEvent());
+    }
+
+    @Override
     public void onCameraLaunchGestureDetected(int source) {
         mLastCameraLaunchSource = source;
         if (mStartedGoingToSleep) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index f61f31e..a40aa83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -42,6 +42,7 @@
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarIconView;
@@ -116,8 +117,8 @@
         mStatusIcons = (LinearLayout) statusBar.findViewById(R.id.statusIcons);
         mSignalCluster = (SignalClusterView) statusBar.findViewById(R.id.signal_cluster);
 
-        mNotificationIconAreaController =
-                new NotificationIconAreaController(context, phoneStatusBar);
+        mNotificationIconAreaController = SystemUIFactory.getInstance()
+                .createNotificationIconAreaController(context, phoneStatusBar);
         mNotificationIconAreaInner =
                 mNotificationIconAreaController.getNotificationInnerAreaView();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index ada7450..b271380 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -138,11 +138,7 @@
             mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         }
 
-        if (state.remoteInputActive) {
-            mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
-        } else {
-            mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-        }
+        mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
     }
 
     private void applyHeight(State state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 0442ac3..2783ec5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -37,22 +37,14 @@
         super(context, theme);
         mContext = context;
 
-        getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        applyFlags(this);
         WindowManager.LayoutParams attrs = getWindow().getAttributes();
         attrs.setTitle(getClass().getSimpleName());
         getWindow().setAttributes(attrs);
     }
 
     public void setShowForAllUsers(boolean show) {
-        if (show) {
-            getWindow().getAttributes().privateFlags |=
-                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-        } else {
-            getWindow().getAttributes().privateFlags &=
-                    ~WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-        }
+        setShowForAllUsers(this, show);
     }
 
     public void setMessage(int resId) {
@@ -66,4 +58,20 @@
     public void setNegativeButton(int resId, OnClickListener onClick) {
         setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
     }
+
+    public static void setShowForAllUsers(AlertDialog dialog, boolean show) {
+        if (show) {
+            dialog.getWindow().getAttributes().privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        } else {
+            dialog.getWindow().getAttributes().privateFlags &=
+                    ~WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        }
+    }
+
+    public static void applyFlags(AlertDialog dialog) {
+        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+        dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 3a0336b..1f4ef4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -46,7 +46,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.RemoteInputController;
-import com.android.systemui.statusbar.stack.LongPressCancelable;
+import com.android.systemui.statusbar.stack.ScrollContainer;
 
 /**
  * Host for the remote input.
@@ -67,7 +67,9 @@
     private RemoteInputController mController;
 
     private NotificationData.Entry mEntry;
-    private LongPressCancelable mLongPressCancelable;
+
+    private ScrollContainer mScrollContainer;
+    private View mScrollContainerChild;
 
     public RemoteInputView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -106,7 +108,7 @@
         mEditText.setOnClickListener(this);
         mEditText.addTextChangedListener(this);
         mEditText.setInnerFocusable(false);
-        mEditText.mDefocusListener = this;
+        mEditText.mRemoteInputView = this;
     }
 
     private void sendRemoteInput() {
@@ -237,23 +239,34 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            if (mLongPressCancelable == null) {
-                ViewParent p = getParent();
-                while (p != null) {
-                    if (p instanceof LongPressCancelable) {
-                        mLongPressCancelable = (LongPressCancelable) p;
-                        break;
-                    }
-                    p = p.getParent();
-                }
-            }
-            if (mLongPressCancelable != null) {
-                mLongPressCancelable.requestDisallowLongPress();
+            findScrollContainer();
+            if (mScrollContainer != null) {
+                mScrollContainer.requestDisallowLongPress();
             }
         }
         return super.onInterceptTouchEvent(ev);
     }
 
+    public boolean requestScrollTo() {
+        findScrollContainer();
+        mScrollContainer.scrollTo(mScrollContainerChild);
+        return true;
+    }
+
+    private void findScrollContainer() {
+        if (mScrollContainer == null) {
+            ViewParent p = this;
+            while (p != null) {
+                if (p.getParent() instanceof ScrollContainer) {
+                    mScrollContainer = (ScrollContainer) p.getParent();
+                    mScrollContainerChild = (View) p;
+                    break;
+                }
+                p = p.getParent();
+            }
+        }
+    }
+
     /**
      * An EditText that changes appearance based on whether it's focusable and becomes
      * un-focusable whenever the user navigates away from it or it becomes invisible.
@@ -261,7 +274,7 @@
     public static class RemoteEditText extends EditText {
 
         private final Drawable mBackground;
-        private RemoteInputView mDefocusListener;
+        private RemoteInputView mRemoteInputView;
         boolean mShowImeOnInputConnection;
 
         public RemoteEditText(Context context, AttributeSet attrs) {
@@ -270,13 +283,13 @@
         }
 
         private void defocusIfNeeded() {
-            if (mDefocusListener.mEntry.row.isChangingPosition()) {
+            if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition()) {
                 return;
             }
             if (isFocusable() && isEnabled()) {
                 setInnerFocusable(false);
-                if (mDefocusListener != null) {
-                    mDefocusListener.onDefocus();
+                if (mRemoteInputView != null) {
+                    mRemoteInputView.onDefocus();
                 }
                 mShowImeOnInputConnection = false;
             }
@@ -300,13 +313,6 @@
         }
 
         @Override
-        public boolean requestRectangleOnScreen(Rect r) {
-            r.top = mScrollY;
-            r.bottom = mScrollY + (mBottom - mTop);
-            return super.requestRectangleOnScreen(r);
-        }
-
-        @Override
         public void getFocusedRect(Rect r) {
             super.getFocusedRect(r);
             r.top = mScrollY;
@@ -314,6 +320,11 @@
         }
 
         @Override
+        public boolean requestRectangleOnScreen(Rect rectangle) {
+            return mRemoteInputView.requestScrollTo();
+        }
+
+        @Override
         public boolean onKeyPreIme(int keyCode, KeyEvent event) {
             if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
                 defocusIfNeeded();
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 bc276b7..b5030e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -43,6 +43,7 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
+import android.view.WindowInsets;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.OverScroller;
@@ -83,7 +84,7 @@
 public class NotificationStackScrollLayout extends ViewGroup
         implements SwipeHelper.Callback, ExpandHelper.Callback, ScrollAdapter,
         ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener,
-        SettingsIconRowListener, LongPressCancelable {
+        SettingsIconRowListener, ScrollContainer {
 
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "StackScroller";
@@ -134,7 +135,7 @@
     private int mPaddingBetweenElements;
     private int mIncreasedPaddingBetweenElements;
     private int mTopPadding;
-    private int mCollapseSecondCardPadding;
+    private int mBottomInset = 0;
 
     /**
      * The algorithm which calculates the properties for our children
@@ -206,6 +207,7 @@
     private float mStackTranslation;
     private float mTopPaddingOverflow;
     private boolean mDontReportNextOverScroll;
+    private boolean mDontClampNextScroll;
     private boolean mRequestViewResizeAnimationOnLayout;
     private boolean mNeedViewResizeAnimation;
     private View mExpandedGroupView;
@@ -919,6 +921,45 @@
         mScrollingEnabled = enable;
     }
 
+    public void scrollTo(View v) {
+        ExpandableView expandableView = (ExpandableView) v;
+        int positionInLinearLayout = getPositionInLinearLayout(v);
+
+        int targetScroll = positionInLinearLayout + expandableView.getActualHeight() +
+                mBottomInset - getHeight() + getTopPadding();
+        if (mOwnScrollY < targetScroll) {
+            mScroller.startScroll(mScrollX, mOwnScrollY, 0, targetScroll - mOwnScrollY);
+            mDontReportNextOverScroll = true;
+            postInvalidateOnAnimation();
+        }
+    }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        mBottomInset = Math.max(0, insets.getSystemWindowInsetBottom()
+                - (getRootView().getHeight() - getHeight()));
+
+        int range = getScrollRange();
+        if (mOwnScrollY > range) {
+            // HACK: We're repeatedly getting staggered insets here while the IME is
+            // animating away. To work around that we'll wait until things have settled.
+            removeCallbacks(mReclamp);
+            postDelayed(mReclamp, 50);
+        }
+        return insets;
+    }
+
+    private Runnable mReclamp = new Runnable() {
+        @Override
+        public void run() {
+            int range = getScrollRange();
+            mScroller.startScroll(mScrollX, mOwnScrollY, 0, range - mOwnScrollY);
+            mDontReportNextOverScroll = true;
+            mDontClampNextScroll = true;
+            postInvalidateOnAnimation();
+        }
+    };
+
     public void setExpandingEnabled(boolean enable) {
         mExpandHelper.setEnabled(enable);
     }
@@ -1256,7 +1297,7 @@
             int y = mScroller.getCurrY();
 
             if (oldX != x || oldY != y) {
-                final int range = getScrollRange();
+                int range = getScrollRange();
                 if (y < 0 && oldY >= 0 || y > range && oldY <= range) {
                     float currVelocity = mScroller.getCurrVelocity();
                     if (currVelocity >= mMinimumVelocity) {
@@ -1264,6 +1305,9 @@
                     }
                 }
 
+                if (mDontClampNextScroll) {
+                    range = Math.max(range, oldY);
+                }
                 overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, range,
                         0, (int) (mMaxOverScroll), false);
                 onScrollChanged(mScrollX, mOwnScrollY, oldX, oldY);
@@ -1271,6 +1315,8 @@
 
             // Keep on drawing until the animation has finished.
             postInvalidateOnAnimation();
+        } else {
+            mDontClampNextScroll = false;
         }
     }
 
@@ -1474,7 +1520,9 @@
                         - firstChild.getMinHeight());
             }
         }
-        return scrollRange;
+        int imeOverlap = Math.max(0,
+                getContentHeight() - (getHeight() - mBottomInset));
+        return scrollRange + imeOverlap;
     }
 
     /**
@@ -2015,6 +2063,14 @@
         }
     }
 
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        super.requestDisallowInterceptTouchEvent(disallowIntercept);
+        if (disallowIntercept) {
+            mSwipeHelper.removeLongPressCallback();
+        }
+    }
+
     private void onViewRemovedInternal(View child) {
         if (mChangePositionInProgress) {
             // This is only a position change, don't do anything special
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/LongPressCancelable.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ScrollContainer.java
similarity index 72%
rename from packages/SystemUI/src/com/android/systemui/statusbar/stack/LongPressCancelable.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/stack/ScrollContainer.java
index 05f0c07..a35465e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/LongPressCancelable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ScrollContainer.java
@@ -16,13 +16,21 @@
 
 package com.android.systemui.statusbar.stack;
 
+import android.view.View;
+
 /**
- * Interface for container layouts that listen for long presses. A child that
- * wants to handle long press can use this to cancel the parents long press logic.
+ * Interface for container layouts that scroll and listen for long presses. A child that
+ * wants to handle long press can use this to cancel the parents long press logic or request
+ * to be made visible by scrolling to it.
  */
-public interface LongPressCancelable {
+public interface ScrollContainer {
     /**
      * Request that the view does not perform long press for the current touch.
      */
     void requestDisallowLongPress();
+
+    /**
+     * Request that the view is made visible by scrolling to it.
+     */
+    void scrollTo(View v);
 }
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 2524e1a..f9bb5e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -171,6 +171,10 @@
     }
 
     @Override
+    public void appTransitionFinished() {
+    }
+
+    @Override
     public void onCameraLaunchGestureDetected(int source) {
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
index 26e1d46..fe44502 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NightModeTile.java
@@ -15,10 +15,7 @@
  */
 package com.android.systemui.tuner;
 
-import android.app.ActivityManager;
 import android.content.Intent;
-import android.provider.Settings;
-
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
@@ -26,8 +23,6 @@
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.NightModeController;
 
-import java.util.Objects;
-
 
 public class NightModeTile extends QSTile<QSTile.State> implements NightModeController.Listener {
 
@@ -81,6 +76,11 @@
     }
 
     @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.night_mode);
+    }
+
+    @Override
     protected void handleUpdateState(State state, Object arg) {
         // TODO: Right now this is just a dropper, needs an actual night icon.
         boolean enabled = mNightModeController.isEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java
new file mode 100644
index 0000000..0e64dcd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlsView.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.tv.pip;
+
+import android.app.Activity;
+import android.content.Context;
+import android.media.session.MediaController;
+import android.media.session.PlaybackState;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.LinearLayout;
+import android.util.AttributeSet;
+
+import com.android.systemui.R;
+
+import static android.media.session.PlaybackState.ACTION_PAUSE;
+import static android.media.session.PlaybackState.ACTION_PLAY;
+
+import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PLAYING;
+import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PAUSED;
+import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_UNAVAILABLE;
+
+
+/**
+ * A view containing PIP controls including fullscreen, close, and media controls.
+ */
+public class PipControlsView extends LinearLayout implements PipManager.Listener {
+    /**
+     * An interface to listen user action.
+     */
+    public interface Listener {
+        /**
+         * Called when an user clicks close PIP button.
+         */
+        void onClosed();
+    }
+
+    private final PipManager mPipManager = PipManager.getInstance();
+    private MediaController mMediaController;
+    private Listener mListener;
+
+    private View mFullButtonView;
+    private View mFullDescriptionView;
+    private View mPlayPauseView;
+    private ImageView mPlayPauseButtonImageView;
+    private TextView mPlayPauseDescriptionTextView;
+    private View mCloseButtonView;
+    private View mCloseDescriptionView;
+
+    private boolean mHasFocus;
+    private OnFocusChangeListener mOnChildFocusChangeListener;
+
+    private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            updatePlayPauseView();
+        }
+    };
+
+    public PipControlsView(Context context) {
+        this(context, null, 0, 0);
+    }
+
+    public PipControlsView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0, 0);
+    }
+
+    public PipControlsView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PipControlsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public void onFinishInflate() {
+        super.onFinishInflate();
+
+        mFullButtonView = findViewById(R.id.full_button);
+        mFullDescriptionView = findViewById(R.id.full_desc);
+        mFullButtonView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mPipManager.movePipToFullscreen();
+            }
+        });
+        mFullButtonView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                mFullDescriptionView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
+                onChildViewFocusChanged();
+            }
+        });
+
+        mPlayPauseView = findViewById(R.id.play_pause);
+        mPlayPauseButtonImageView = (ImageView) findViewById(R.id.play_pause_button);
+        mPlayPauseDescriptionTextView = (TextView) findViewById(R.id.play_pause_desc);
+        mPlayPauseButtonImageView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mMediaController == null || mMediaController.getPlaybackState() == null) {
+                    return;
+                }
+                long actions = mMediaController.getPlaybackState().getActions();
+                int state = mMediaController.getPlaybackState().getState();
+                if (mPipManager.getPlaybackState() == PLAYBACK_STATE_PAUSED) {
+                    mMediaController.getTransportControls().play();
+                } else if (mPipManager.getPlaybackState() == PLAYBACK_STATE_PLAYING) {
+                    mMediaController.getTransportControls().pause();
+                }
+                // View will be updated later in {@link mMediaControllerCallback}
+            }
+        });
+        mPlayPauseButtonImageView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                mPlayPauseDescriptionTextView.setVisibility(
+                        hasFocus ? View.VISIBLE : View.INVISIBLE);
+                onChildViewFocusChanged();
+            }
+        });
+
+        mCloseButtonView = findViewById(R.id.close_button);
+        mCloseDescriptionView = findViewById(R.id.close_desc);
+        mCloseButtonView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mPipManager.closePip();
+                mListener.onClosed();
+            }
+        });
+        mCloseButtonView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                mCloseDescriptionView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
+                onChildViewFocusChanged();
+            }
+        });
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        updateMediaController();
+        mPipManager.addListener(this);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mPipManager.removeListener(this);
+        if (mMediaController != null) {
+            mMediaController.unregisterCallback(mMediaControllerCallback);
+        }
+    }
+
+    private void updateMediaController() {
+        MediaController newController = mPipManager.getMediaController();
+        if (mMediaController == newController) {
+            return;
+        }
+        if (mMediaController != null) {
+            mMediaController.unregisterCallback(mMediaControllerCallback);
+        }
+        mMediaController = newController;
+        if (mMediaController != null) {
+            mMediaController.registerCallback(mMediaControllerCallback);
+        }
+        updatePlayPauseView();
+    }
+
+    private void updatePlayPauseView() {
+        int state = mPipManager.getPlaybackState();
+        if (state == PLAYBACK_STATE_UNAVAILABLE) {
+            mPlayPauseView.setVisibility(View.GONE);
+        } else {
+            mPlayPauseView.setVisibility(View.VISIBLE);
+            if (state == PLAYBACK_STATE_PLAYING) {
+                mPlayPauseButtonImageView.setImageResource(R.drawable.tv_pip_pause_button);
+                mPlayPauseDescriptionTextView.setText(R.string.pip_pause);
+            } else {
+                mPlayPauseButtonImageView.setImageResource(R.drawable.tv_pip_play_button);
+                mPlayPauseDescriptionTextView.setText(R.string.pip_play);
+            }
+        }
+    }
+
+    /**
+     * Sets a listener to be invoked when {@link android.view.View.hasFocus()} is changed.
+     */
+    public void setOnChildFocusChangeListener(OnFocusChangeListener listener) {
+        mOnChildFocusChangeListener = listener;
+    }
+
+    private void onChildViewFocusChanged() {
+        // At this moment, hasFocus() returns true although there's no focused child.
+        boolean hasFocus = (mFullButtonView != null && mFullButtonView.isFocused())
+                || (mPlayPauseButtonImageView != null && mPlayPauseButtonImageView.isFocused())
+                || (mCloseButtonView != null && mCloseButtonView.isFocused());
+        if (mHasFocus != hasFocus) {
+            mHasFocus = hasFocus;
+            if (mOnChildFocusChangeListener != null) {
+                mOnChildFocusChangeListener.onFocusChange(getFocusedChild(), mHasFocus);
+            }
+        }
+    }
+
+    /**
+     * Sets the {@link Listener} to listen user actions.
+     */
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void onPipEntered() { }
+
+    @Override
+    public void onPipActivityClosed() { }
+
+    @Override
+    public void onShowPipMenu() { }
+
+    @Override
+    public void onMoveToFullscreen() { }
+
+    @Override
+    public void onMediaControllerChanged() {
+        updateMediaController();
+    }
+
+    @Override
+    public void onPipResizeAboutToStart() { }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index 95cee4c..68e0883 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -21,7 +21,6 @@
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.IActivityManager;
-import android.app.ITaskStackListener;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -31,6 +30,7 @@
 import android.graphics.Rect;
 import android.media.session.MediaController;
 import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -38,6 +38,9 @@
 import android.util.Log;
 
 import com.android.systemui.Prefs;
+import com.android.systemui.R;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -69,12 +72,23 @@
     public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH = 0x1;
     public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH = 0x2;
 
+    /**
+     * PIPed activity is playing a media and it can be paused.
+     */
+    static final int PLAYBACK_STATE_PLAYING = 0;
+    /**
+     * PIPed activity has a paused media and it can be played.
+     */
+    static final int PLAYBACK_STATE_PAUSED = 1;
+    /**
+     * Users are unable to control PIPed activity's media playback.
+     */
+    static final int PLAYBACK_STATE_UNAVAILABLE = 2;
+
     private static final int CLOSE_PIP_WHEN_MEDIA_SESSION_GONE_TIMEOUT_MS = 3000;
 
     private int mSuspendPipResizingReason;
 
-    private static final float SCALE_FACTOR = 1.1f;
-
     private Context mContext;
     private IActivityManager mActivityManager;
     private MediaSessionManager mMediaSessionManager;
@@ -86,6 +100,7 @@
     private Rect mMenuModePipBounds;
     private Rect mRecentsPipBounds;
     private Rect mRecentsFocusedPipBounds;
+    private int mRecentsFocusChangedAnimationDurationMs;
     private boolean mInitialized;
     private int mPipTaskId = TASK_ID_NO_PIP;
     private ComponentName mPipComponentName;
@@ -95,89 +110,6 @@
     private boolean mIsRecentsShown;
     private boolean mIsPipFocusedInRecent;
 
-    private final Runnable mOnActivityPinnedRunnable = new Runnable() {
-        @Override
-        public void run() {
-            StackInfo stackInfo = null;
-            try {
-                stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
-                if (stackInfo == null) {
-                    Log.w(TAG, "Cannot find pinned stack");
-                    return;
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "getStackInfo failed", e);
-                return;
-            }
-            if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
-            mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
-            mPipComponentName = ComponentName.unflattenFromString(
-                    stackInfo.taskNames[stackInfo.taskNames.length - 1]);
-            // Set state to overlay so we show it when the pinned stack animation ends.
-            mState = STATE_PIP_OVERLAY;
-            mCurrentPipBounds = mPipBounds;
-            launchPipOnboardingActivityIfNeeded();
-            mMediaSessionManager.addOnActiveSessionsChangedListener(
-                    mActiveMediaSessionListener, null);
-            updateMediaController(mMediaSessionManager.getActiveSessions(null));
-            if (mIsRecentsShown) {
-                // If an activity becomes PIPed again after the fullscreen, the Recents is shown
-                // behind so we need to resize the pinned stack and show the correct overlay.
-                resizePinnedStack(STATE_PIP_OVERLAY);
-            }
-            for (int i = mListeners.size() - 1; i >= 0; i--) {
-                mListeners.get(i).onPipEntered();
-            }
-        }
-    };
-    private final Runnable mOnTaskStackChanged = new Runnable() {
-        @Override
-        public void run() {
-            if (mState != STATE_NO_PIP) {
-                StackInfo stackInfo = null;
-                try {
-                    stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
-                    if (stackInfo == null) {
-                        Log.w(TAG, "There is no pinned stack");
-                        closePipInternal(false);
-                        return;
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "getStackInfo failed", e);
-                    return;
-                }
-                for (int i = stackInfo.taskIds.length - 1; i >= 0; --i) {
-                    if (stackInfo.taskIds[i] == mPipTaskId) {
-                        // PIP task is still alive.
-                        return;
-                    }
-                }
-                // PIP task doesn't exist anymore in PINNED_STACK.
-                closePipInternal(true);
-            }
-        }
-    };
-    private final Runnable mOnPinnedActivityRestartAttempt = new Runnable() {
-        @Override
-        public void run() {
-            // If PIPed activity is launched again by Launcher or intent, make it fullscreen.
-            movePipToFullscreen();
-        }
-    };
-    private final Runnable mOnPinnedStackAnimationEnded = new Runnable() {
-        @Override
-        public void run() {
-            switch (mState) {
-                case STATE_PIP_OVERLAY:
-                    showPipOverlay();
-                    break;
-                case STATE_PIP_MENU:
-                    showPipMenu();
-                    break;
-            }
-        }
-    };
-
     private final Runnable mResizePinnedStackRunnable = new Runnable() {
         @Override
         public void run() {
@@ -230,24 +162,16 @@
         mPipBounds = Rect.unflattenFromString(res.getString(
                 com.android.internal.R.string.config_defaultPictureInPictureBounds));
         mMenuModePipBounds = Rect.unflattenFromString(res.getString(
-                com.android.internal.R.string.config_centeredPictureInPictureBounds));
+                R.string.pip_menu_bounds));
         mRecentsPipBounds = Rect.unflattenFromString(res.getString(
-                com.android.internal.R.string.config_pictureInPictureBoundsInRecents));
-        float scaleBy = (SCALE_FACTOR - 1.0f) / 2;
-        mRecentsFocusedPipBounds = new Rect(
-                (int) (mRecentsPipBounds.left - scaleBy * mRecentsPipBounds.width()),
-                (int) (mRecentsPipBounds.top - scaleBy * mRecentsPipBounds.height()),
-                (int) (mRecentsPipBounds.right + scaleBy * mRecentsPipBounds.width()),
-                (int) (mRecentsPipBounds.bottom + scaleBy * mRecentsPipBounds.height()));
+                R.string.pip_recents_bounds));
+        mRecentsFocusedPipBounds = Rect.unflattenFromString(res.getString(
+                R.string.pip_recents_focused_bounds));
+        mRecentsFocusChangedAnimationDurationMs = res.getInteger(
+                R.integer.recents_tv_pip_focus_anim_duration);
 
         mActivityManager = ActivityManagerNative.getDefault();
-        TaskStackListener taskStackListener = new TaskStackListener();
-        IActivityManager iam = ActivityManagerNative.getDefault();
-        try {
-            iam.registerTaskStackListener(taskStackListener);
-        } catch (RemoteException e) {
-            Log.e(TAG, "registerTaskStackListener failed", e);
-        }
+        SystemServicesProxy.getInstance(context).registerTaskStackListener(mTaskStackListener);
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
         mContext.registerReceiver(mBroadcastReceiver, intentFilter);
@@ -367,6 +291,7 @@
                             mSuspendPipResizingReason);
             return;
         }
+        int animationDurationMs = -1;
         switch (mState) {
             case STATE_NO_PIP:
                 mCurrentPipBounds = null;
@@ -376,6 +301,10 @@
                 break;
             case STATE_PIP_OVERLAY:
                 if (mIsRecentsShown) {
+                    if (mCurrentPipBounds == mRecentsFocusedPipBounds
+                            || mCurrentPipBounds == mRecentsFocusedPipBounds) {
+                        animationDurationMs = mRecentsFocusChangedAnimationDurationMs;
+                    }
                     if (mIsPipFocusedInRecent) {
                         mCurrentPipBounds = mRecentsFocusedPipBounds;
                     } else {
@@ -390,7 +319,8 @@
                 break;
         }
         try {
-            mActivityManager.resizeStack(PINNED_STACK_ID, mCurrentPipBounds, true, true, true, -1);
+            mActivityManager.resizeStack(PINNED_STACK_ID, mCurrentPipBounds,
+                    true, true, true, animationDurationMs);
         } catch (RemoteException e) {
             Log.e(TAG, "resizeStack failed", e);
         }
@@ -452,9 +382,17 @@
     }
 
     /**
+     * Returns {@code true} if the PIP view in
+     * {@link com.android.systemui.recents.tv.RecentsTvActivity} is focused in Recents.
+     * This API is valid only when {@link isRecentsShown()} returns {@code true}.
+     */
+    boolean isPipViewFocusdInRecents() {
+        return mIsPipFocusedInRecent;
+    }
+
+    /**
      * Shows PIP menu UI by launching {@link PipMenuActivity}. It also locates the pinned
-     * stack to the centered PIP bound {@link com.android.internal.R.string
-     * .config_centeredPictureInPictureBounds}.
+     * stack to the centered PIP bound {@link R.config_centeredPictureInPictureBounds}.
      */
     private void showPipMenu() {
         if (DEBUG) Log.d(TAG, "showPipMenu()");
@@ -566,33 +504,114 @@
         return mPipMediaController;
     }
 
-    private class TaskStackListener extends ITaskStackListener.Stub {
+    /**
+     * Returns the PIPed activity's playback state.
+     * This returns one of {@link PLAYBACK_STATE_PLAYING}, {@link PLAYBACK_STATE_PAUSED},
+     * or {@link PLAYBACK_STATE_UNAVAILABLE}.
+     */
+    int getPlaybackState() {
+        if (mPipMediaController == null || mPipMediaController.getPlaybackState() == null) {
+            return PLAYBACK_STATE_UNAVAILABLE;
+        }
+        int state = mPipMediaController.getPlaybackState().getState();
+        boolean isPlaying = (state == PlaybackState.STATE_BUFFERING
+                || state == PlaybackState.STATE_CONNECTING
+                || state == PlaybackState.STATE_PLAYING
+                || state == PlaybackState.STATE_FAST_FORWARDING
+                || state == PlaybackState.STATE_REWINDING
+                || state == PlaybackState.STATE_SKIPPING_TO_PREVIOUS
+                || state == PlaybackState.STATE_SKIPPING_TO_NEXT);
+        long actions = mPipMediaController.getPlaybackState().getActions();
+        if (!isPlaying && ((actions & PlaybackState.ACTION_PLAY) != 0)) {
+            return PLAYBACK_STATE_PAUSED;
+        } else if (isPlaying && ((actions & PlaybackState.ACTION_PAUSE) != 0)) {
+            return PLAYBACK_STATE_PLAYING;
+        }
+        return PLAYBACK_STATE_UNAVAILABLE;
+    }
+
+    TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
-        public void onTaskStackChanged() throws RemoteException {
-            // Post the message back to the UI thread.
-            mHandler.post(mOnTaskStackChanged);
+        public void onTaskStackChanged() {
+            if (mState != STATE_NO_PIP) {
+                StackInfo stackInfo = null;
+                try {
+                    stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+                    if (stackInfo == null) {
+                        Log.w(TAG, "There is no pinned stack");
+                        closePipInternal(false);
+                        return;
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "getStackInfo failed", e);
+                    return;
+                }
+                for (int i = stackInfo.taskIds.length - 1; i >= 0; --i) {
+                    if (stackInfo.taskIds[i] == mPipTaskId) {
+                        // PIP task is still alive.
+                        return;
+                    }
+                }
+                // PIP task doesn't exist anymore in PINNED_STACK.
+                closePipInternal(true);
+            }
         }
 
         @Override
-        public void onActivityPinned()  throws RemoteException {
-            // Post the message back to the UI thread.
+        public void onActivityPinned() {
             if (DEBUG) Log.d(TAG, "onActivityPinned()");
-            mHandler.post(mOnActivityPinnedRunnable);
+            StackInfo stackInfo = null;
+            try {
+                stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+                if (stackInfo == null) {
+                    Log.w(TAG, "Cannot find pinned stack");
+                    return;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "getStackInfo failed", e);
+                return;
+            }
+            if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
+            mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
+            mPipComponentName = ComponentName.unflattenFromString(
+                    stackInfo.taskNames[stackInfo.taskNames.length - 1]);
+            // Set state to overlay so we show it when the pinned stack animation ends.
+            mState = STATE_PIP_OVERLAY;
+            mCurrentPipBounds = mPipBounds;
+            launchPipOnboardingActivityIfNeeded();
+            mMediaSessionManager.addOnActiveSessionsChangedListener(
+                    mActiveMediaSessionListener, null);
+            updateMediaController(mMediaSessionManager.getActiveSessions(null));
+            if (mIsRecentsShown) {
+                // If an activity becomes PIPed again after the fullscreen, the Recents is shown
+                // behind so we need to resize the pinned stack and show the correct overlay.
+                resizePinnedStack(STATE_PIP_OVERLAY);
+            }
+            for (int i = mListeners.size() - 1; i >= 0; i--) {
+                mListeners.get(i).onPipEntered();
+            }
         }
 
         @Override
         public void onPinnedActivityRestartAttempt() {
-            // Post the message back to the UI thread.
             if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
-            mHandler.post(mOnPinnedActivityRestartAttempt);
+            // If PIPed activity is launched again by Launcher or intent, make it fullscreen.
+            movePipToFullscreen();
         }
 
         @Override
         public void onPinnedStackAnimationEnded() {
             if (DEBUG) Log.d(TAG, "onPinnedStackAnimationEnded()");
-            mHandler.post(mOnPinnedStackAnimationEnded);
+            switch (mState) {
+                case STATE_PIP_OVERLAY:
+                    showPipOverlay();
+                    break;
+                case STATE_PIP_MENU:
+                    showPipMenu();
+                    break;
+            }
         }
-    }
+    };
 
     /**
      * A listener interface to receive notification on changes in PIP.
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
index b8b837a..ea9275f 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
@@ -17,12 +17,7 @@
 package com.android.systemui.tv.pip;
 
 import android.app.Activity;
-import android.media.session.MediaController;
-import android.media.session.PlaybackState;
 import android.os.Bundle;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
 
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
@@ -31,8 +26,6 @@
 
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
-import static android.media.session.PlaybackState.ACTION_PAUSE;
-import static android.media.session.PlaybackState.ACTION_PLAY;
 
 /**
  * Activity to show the PIP menu to control PIP.
@@ -41,131 +34,17 @@
     private static final String TAG = "PipMenuActivity";
 
     private final PipManager mPipManager = PipManager.getInstance();
-    private MediaController mMediaController;
 
-    private View mFullButtonView;
-    private View mFullDescriptionView;
-    private View mPlayPauseView;
-    private ImageView mPlayPauseButtonImageView;
-    private TextView mPlayPauseDescriptionTextView;
-    private View mCloseButtonView;
-    private View mCloseDescriptionView;
+    private PipControlsView mPipControlsView;
     private boolean mPipMovedToFullscreen;
 
-    private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
-        @Override
-        public void onPlaybackStateChanged(PlaybackState state) {
-            updatePlayPauseView(state);
-        }
-    };
-
     @Override
     protected void onCreate(Bundle bundle) {
         super.onCreate(bundle);
         setContentView(R.layout.tv_pip_menu);
         mPipManager.addListener(this);
-        mFullButtonView = findViewById(R.id.full_button);
-        mFullDescriptionView = findViewById(R.id.full_desc);
-        mFullButtonView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mPipManager.movePipToFullscreen();
-                mPipMovedToFullscreen = true;
-                finish();
-            }
-        });
-        mFullButtonView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                mFullDescriptionView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
-            }
-        });
 
-        mPlayPauseView = findViewById(R.id.play_pause);
-        mPlayPauseButtonImageView = (ImageView) findViewById(R.id.play_pause_button);
-        mPlayPauseDescriptionTextView = (TextView) findViewById(R.id.play_pause_desc);
-        mPlayPauseButtonImageView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mMediaController == null || mMediaController.getPlaybackState() == null) {
-                    return;
-                }
-                long actions = mMediaController.getPlaybackState().getActions();
-                int state = mMediaController.getPlaybackState().getState();
-                if (((actions & ACTION_PLAY) != 0) && !isPlaying(state)) {
-                    mMediaController.getTransportControls().play();
-                } else if ((actions & ACTION_PAUSE) != 0 && isPlaying(state)) {
-                    mMediaController.getTransportControls().pause();
-                }
-                // View will be updated later in {@link mMediaControllerCallback}
-            }
-        });
-        mPlayPauseButtonImageView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                mPlayPauseDescriptionTextView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
-            }
-        });
-
-        mCloseButtonView = findViewById(R.id.close_button);
-        mCloseDescriptionView = findViewById(R.id.close_desc);
-        mCloseButtonView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mPipManager.closePip();
-                finish();
-            }
-        });
-        mCloseButtonView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                mCloseDescriptionView.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
-            }
-        });
-        updateMediaController();
-    }
-
-    private void updateMediaController() {
-        MediaController newController = mPipManager.getMediaController();
-        if (mMediaController == newController) {
-            return;
-        }
-        if (mMediaController != null) {
-            mMediaController.unregisterCallback(mMediaControllerCallback);
-        }
-        mMediaController = newController;
-        if (mMediaController != null) {
-            mMediaController.registerCallback(mMediaControllerCallback);
-            updatePlayPauseView(mMediaController.getPlaybackState());
-        } else {
-            updatePlayPauseView(null);
-        }
-    }
-
-    private void updatePlayPauseView(PlaybackState playbackState) {
-        if (playbackState != null
-                && (playbackState.getActions() & (ACTION_PLAY | ACTION_PAUSE)) != 0) {
-            mPlayPauseView.setVisibility(View.VISIBLE);
-            if (isPlaying(playbackState.getState())) {
-                mPlayPauseButtonImageView.setImageResource(R.drawable.tv_pip_pause_button);
-                mPlayPauseDescriptionTextView.setText(R.string.pip_pause);
-            } else {
-                mPlayPauseButtonImageView.setImageResource(R.drawable.tv_pip_play_button);
-                mPlayPauseDescriptionTextView.setText(R.string.pip_play);
-            }
-        } else {
-            mPlayPauseView.setVisibility(View.GONE);
-        }
-    }
-
-    private boolean isPlaying(int state) {
-        return state == PlaybackState.STATE_BUFFERING
-                || state == PlaybackState.STATE_CONNECTING
-                || state == PlaybackState.STATE_PLAYING
-                || state == PlaybackState.STATE_FAST_FORWARDING
-                || state == PlaybackState.STATE_REWINDING
-                || state == PlaybackState.STATE_SKIPPING_TO_PREVIOUS
-                || state == PlaybackState.STATE_SKIPPING_TO_NEXT;
+        mPipControlsView = (PipControlsView) findViewById(R.id.pip_controls);
     }
 
     private void restorePipAndFinish() {
@@ -184,9 +63,6 @@
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        if (mMediaController != null) {
-            mMediaController.unregisterCallback(mMediaControllerCallback);
-        }
         mPipManager.removeListener(this);
         mPipManager.resumePipResizing(
                 PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
@@ -210,13 +86,12 @@
 
     @Override
     public void onMoveToFullscreen() {
+        mPipMovedToFullscreen = true;
         finish();
     }
 
     @Override
-    public void onMediaControllerChanged() {
-        updateMediaController();
-    }
+    public void onMediaControllerChanged() { }
 
     @Override
     public void onPipResizeAboutToStart() {
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
index 1de321d..12cb4cd7 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
@@ -23,6 +23,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.view.View;
+import android.widget.ImageView;
 
 import com.android.systemui.R;
 
@@ -46,9 +47,10 @@
     private final Handler mHandler = new Handler();
     private View mGuideOverlayView;
     private View mGuideButtonsView;
+    private ImageView mGuideButtonPlayPauseImageView;
     private final Runnable mHideGuideOverlayRunnable = new Runnable() {
         public void run() {
-            mGuideOverlayView.setVisibility(View.INVISIBLE);
+            mGuideOverlayView.setVisibility(View.GONE);
         }
     };
 
@@ -71,6 +73,7 @@
         setContentView(R.layout.tv_pip_overlay);
         mGuideOverlayView = findViewById(R.id.guide_overlay);
         mGuideButtonsView = findViewById(R.id.guide_buttons);
+        mGuideButtonPlayPauseImageView = (ImageView) findViewById(R.id.guide_button_play_pause);
         mPipManager.addListener(this);
 
         sPipOverlayActivity = this;
@@ -80,12 +83,17 @@
     protected void onResume() {
         super.onResume();
         // TODO: Implement animation for this
-        if (!mPipManager.isRecentsShown()) {
-            mGuideOverlayView.setVisibility(View.VISIBLE);
-            mGuideButtonsView.setVisibility(View.INVISIBLE);
+        if (mPipManager.isRecentsShown()) {
+            mGuideOverlayView.setVisibility(View.GONE);
+            if (mPipManager.isPipViewFocusdInRecents()) {
+                mGuideButtonsView.setVisibility(View.GONE);
+            } else {
+                mGuideButtonsView.setVisibility(View.VISIBLE);
+                updateGuideButtonsView();
+            }
         } else {
-            mGuideOverlayView.setVisibility(View.INVISIBLE);
-            mGuideButtonsView.setVisibility(View.VISIBLE);
+            mGuideOverlayView.setVisibility(View.VISIBLE);
+            mGuideButtonsView.setVisibility(View.GONE);
         }
         mHandler.removeCallbacks(mHideGuideOverlayRunnable);
         mHandler.postDelayed(mHideGuideOverlayRunnable, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS);
@@ -134,11 +142,30 @@
     }
 
     @Override
-    public void onMediaControllerChanged() { }
+    public void onMediaControllerChanged() {
+        updateGuideButtonsView();
+    }
 
     @Override
     public void finish() {
         sPipOverlayActivity = null;
         super.finish();
     }
+
+    private void updateGuideButtonsView() {
+        switch (mPipManager.getPlaybackState()) {
+            case PipManager.PLAYBACK_STATE_PLAYING:
+                mGuideButtonPlayPauseImageView.setVisibility(View.VISIBLE);
+                mGuideButtonPlayPauseImageView.setImageResource(R.drawable.ic_pause_white_24dp);
+                break;
+            case PipManager.PLAYBACK_STATE_PAUSED:
+                mGuideButtonPlayPauseImageView.setVisibility(View.VISIBLE);
+                mGuideButtonPlayPauseImageView.setImageResource(
+                        R.drawable.ic_play_arrow_white_24dp);
+                break;
+            case PipManager.PLAYBACK_STATE_UNAVAILABLE:
+                mGuideButtonPlayPauseImageView.setVisibility(View.GONE);
+                break;
+        }
+    }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index e710ded..e3dac28 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1812,6 +1812,87 @@
         return mKeyEventDispatcher;
     }
 
+    /**
+     * Enables accessibility service specified by {@param componentName} for the {@param userId}.
+     */
+    public void enableAccessibilityService(ComponentName componentName, int userId) {
+        synchronized(mLock) {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                throw new SecurityException("only SYSTEM can call enableAccessibilityService.");
+            }
+
+            SettingsStringHelper settingsHelper = new SettingsStringHelper(
+                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId);
+            settingsHelper.addService(componentName);
+            settingsHelper.writeToSettings();
+
+            UserState userState = getUserStateLocked(userId);
+            if (userState.mEnabledServices.add(componentName)) {
+                onUserStateChangedLocked(userState);
+            }
+        }
+    }
+
+    /**
+     * Disables accessibility service specified by {@param componentName} for the {@param userId}.
+     */
+    public void disableAccessibilityService(ComponentName componentName, int userId) {
+        synchronized(mLock) {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                throw new SecurityException("only SYSTEM can call disableAccessibility");
+            }
+
+            SettingsStringHelper settingsHelper = new SettingsStringHelper(
+                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId);
+            settingsHelper.deleteService(componentName);
+            settingsHelper.writeToSettings();
+
+            UserState userState = getUserStateLocked(userId);
+            if (userState.mEnabledServices.remove(componentName)) {
+                onUserStateChangedLocked(userState);
+            }
+        }
+    }
+
+    private class SettingsStringHelper {
+        private static final String SETTINGS_DELIMITER = ":";
+        private ContentResolver mContentResolver;
+        private final String mSettingsName;
+        private Set<String> mServices;
+        private final int mUserId;
+
+        public SettingsStringHelper(String name, int userId) {
+            mUserId = userId;
+            mSettingsName = name;
+            mContentResolver = mContext.getContentResolver();
+            String servicesString = Settings.Secure.getStringForUser(
+                    mContentResolver, mSettingsName, userId);
+            mServices = new HashSet();
+            if (!TextUtils.isEmpty(servicesString)) {
+                final TextUtils.SimpleStringSplitter colonSplitter =
+                        new TextUtils.SimpleStringSplitter(SETTINGS_DELIMITER.charAt(0));
+                colonSplitter.setString(servicesString);
+                while (colonSplitter.hasNext()) {
+                    final String serviceName = colonSplitter.next();
+                    mServices.add(serviceName);
+                }
+            }
+        }
+
+        public void addService(ComponentName component) {
+            mServices.add(component.flattenToString());
+        }
+
+        public void deleteService(ComponentName component) {
+            mServices.remove(component.flattenToString());
+        }
+
+        public void writeToSettings() {
+            Settings.Secure.putStringForUser(mContentResolver, mSettingsName,
+                    TextUtils.join(SETTINGS_DELIMITER, mServices), mUserId);
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
         mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5b01062..95d3cc3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -71,6 +71,7 @@
 import android.net.RouteInfo;
 import android.net.UidRange;
 import android.net.Uri;
+import android.net.metrics.ConnectivityServiceChangeEvent;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -125,7 +126,6 @@
 import com.android.server.connectivity.NetworkMonitor;
 import com.android.server.connectivity.PacManager;
 import com.android.server.connectivity.PermissionMonitor;
-import com.android.server.connectivity.ApfFilter;
 import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.BaseNetworkObserver;
@@ -354,13 +354,6 @@
      */
     private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
 
-    /**
-     * used to push APF program to NetworkAgent
-     * replyTo = NetworkAgent message handler
-     * obj = byte[] of APF program
-     */
-    private static final int EVENT_PUSH_APF_PROGRAM_TO_NETWORK = 32;
-
     /** Handler thread used for both of the handlers below. */
     @VisibleForTesting
     protected final HandlerThread mHandlerThread;
@@ -630,7 +623,7 @@
 
         mDefaultRequest = createInternetRequestForTransport(-1);
         NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest,
-                new Binder(), NetworkRequestInfo.REQUEST);
+                new Binder(), NetworkRequestType.REQUEST);
         mNetworkRequests.put(mDefaultRequest, defaultNRI);
         mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
 
@@ -806,7 +799,7 @@
 
         if (enable) {
             handleRegisterNetworkRequest(new NetworkRequestInfo(
-                    null, mDefaultMobileDataRequest, new Binder(), NetworkRequestInfo.REQUEST));
+                    null, mDefaultMobileDataRequest, new Binder(), NetworkRequestType.REQUEST));
         } else {
             handleReleaseNetworkRequest(mDefaultMobileDataRequest, Process.SYSTEM_UID);
         }
@@ -1802,20 +1795,6 @@
         }
     }
 
-    private void dumpApf(IndentingPrintWriter pw) {
-        pw.println("APF filters:");
-        pw.increaseIndent();
-        for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
-            if (nai.apfFilter != null) {
-                pw.println(nai.name() + ":");
-                pw.increaseIndent();
-                nai.apfFilter.dump(pw);
-                pw.decreaseIndent();
-            }
-        }
-        pw.decreaseIndent();
-    }
-
     @Override
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -1833,11 +1812,6 @@
             return;
         }
 
-        if (argsContain(args, "apf")) {
-            dumpApf(pw);
-            return;
-        }
-
         pw.print("NetworkFactories for:");
         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
             pw.print(" " + nfi.name);
@@ -1901,7 +1875,6 @@
         mKeepaliveTracker.dump(pw);
 
         pw.println();
-        dumpApf(pw);
 
         if (mInetLog != null && mInetLog.size() > 0) {
             pw.println();
@@ -1945,7 +1918,7 @@
     }
 
     private boolean isRequest(NetworkRequest request) {
-        return mNetworkRequests.get(request).isRequest;
+        return mNetworkRequests.get(request).isRequest();
     }
 
     // must be stateless - things change under us.
@@ -2164,7 +2137,7 @@
                 if (VDBG) log("NetworkFactory connected");
                 // A network factory has connected.  Send it all current NetworkRequests.
                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
-                    if (nri.isRequest == false) continue;
+                    if (!nri.isRequest()) continue;
                     NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
                     ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
                             (nai != null ? nai.getCurrentScore() : 0), 0, nri.request);
@@ -2223,7 +2196,6 @@
             mKeepaliveTracker.handleStopAllKeepalives(nai,
                     ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
             nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
-            if (nai.apfFilter != null) nai.apfFilter.shutdown();
             mNetworkAgentInfos.remove(msg.replyTo);
             updateClat(null, nai.linkProperties, nai);
             synchronized (mNetworkForNetId) {
@@ -2301,7 +2273,7 @@
     private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
         mNetworkRequests.put(nri.request, nri);
         mNetworkRequestInfoLogs.log("REGISTER " + nri);
-        if (!nri.isRequest) {
+        if (!nri.isRequest()) {
             for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
                 if (nri.request.networkCapabilities.hasSignalStrength() &&
                         network.satisfiesImmutableCapabilitiesOf(nri.request)) {
@@ -2310,7 +2282,7 @@
             }
         }
         rematchAllNetworksAndRequests(null, 0);
-        if (nri.isRequest && mNetworkForRequestId.get(nri.request.requestId) == null) {
+        if (nri.isRequest() && mNetworkForRequestId.get(nri.request.requestId) == null) {
             sendUpdatedScoreToFactories(nri.request, 0);
         }
     }
@@ -2331,7 +2303,7 @@
         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
             // If this Network is already the highest scoring Network for a request, or if
             // there is hope for it to become one if it validated, then it is needed.
-            if (nri.isRequest && nai.satisfies(nri.request) &&
+            if (nri.isRequest() && nai.satisfies(nri.request) &&
                     (nai.networkRequests.get(nri.request.requestId) != null ||
                     // Note that this catches two important cases:
                     // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
@@ -2359,7 +2331,7 @@
             nri.unlinkDeathRecipient();
             mNetworkRequests.remove(request);
             mNetworkRequestInfoLogs.log("RELEASE " + nri);
-            if (nri.isRequest) {
+            if (nri.isRequest()) {
                 // Find all networks that are satisfying this request and remove the request
                 // from their request lists.
                 // TODO - it's my understanding that for a request there is only a single
@@ -2438,13 +2410,6 @@
                 accept ? 1 : 0, always ? 1: 0, network));
     }
 
-    public void pushApfProgramToNetwork(NetworkAgentInfo nai, byte[] program) {
-        enforceConnectivityInternalPermission();
-        Message msg = mHandler.obtainMessage(EVENT_PUSH_APF_PROGRAM_TO_NETWORK, program);
-        msg.replyTo = nai.messenger;
-        mHandler.sendMessage(msg);
-    }
-
     private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
         if (DBG) log("handleSetAcceptUnvalidated network=" + network +
                 " accept=" + accept + " always=" + always);
@@ -2594,16 +2559,6 @@
                     handleMobileDataAlwaysOn();
                     break;
                 }
-                case EVENT_PUSH_APF_PROGRAM_TO_NETWORK: {
-                    NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
-                    if (nai == null) {
-                        loge("EVENT_PUSH_APF_PROGRAM_TO_NETWORK from unknown NetworkAgent");
-                    } else {
-                         nai.asyncChannel.sendMessage(NetworkAgent.CMD_PUSH_APF_PROGRAM,
-                                 (byte[]) msg.obj);
-                    }
-                    break;
-                }
                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
                 case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
                     mKeepaliveTracker.handleStartKeepalive(msg);
@@ -3736,13 +3691,36 @@
     }
 
     /**
+     * A NetworkRequest as registered by an application can be one of three
+     * types:
+     *
+     *     - "listen", for which the framework will issue callbacks about any
+     *       and all networks that match the specified NetworkCapabilities,
+     *
+     *     - "request", capable of causing a specific network to be created
+     *       first (e.g. a telephony DUN request), the framework will issue
+     *       callbacks about the single, highest scoring current network
+     *       (if any) that matches the specified NetworkCapabilities, or
+     *
+     *     - "track the default network", a hybrid of the two designed such
+     *       that the framework will issue callbacks for the single, highest
+     *       scoring current network (if any) that matches the capabilities of
+     *       the default Internet request (mDefaultRequest), but which cannot
+     *       cause the framework to either create or retain the existence of
+     *       any specific network.
+     *
+     */
+    private static enum NetworkRequestType {
+        LISTEN,
+        TRACK_DEFAULT,
+        REQUEST
+    };
+
+    /**
      * Tracks info about the requester.
      * Also used to notice when the calling process dies so we can self-expire
      */
     private class NetworkRequestInfo implements IBinder.DeathRecipient {
-        static final boolean REQUEST = true;
-        static final boolean LISTEN = false;
-
         final NetworkRequest request;
         final PendingIntent mPendingIntent;
         boolean mPendingIntentSent;
@@ -3750,26 +3728,26 @@
         final int mPid;
         final int mUid;
         final Messenger messenger;
-        final boolean isRequest;
+        private final NetworkRequestType mType;
 
-        NetworkRequestInfo(NetworkRequest r, PendingIntent pi, boolean isRequest) {
+        NetworkRequestInfo(NetworkRequest r, PendingIntent pi, NetworkRequestType type) {
             request = r;
             mPendingIntent = pi;
             messenger = null;
             mBinder = null;
             mPid = getCallingPid();
             mUid = getCallingUid();
-            this.isRequest = isRequest;
+            mType = type;
         }
 
-        NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, boolean isRequest) {
+        NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) {
             super();
             messenger = m;
             request = r;
             mBinder = binder;
             mPid = getCallingPid();
             mUid = getCallingUid();
-            this.isRequest = isRequest;
+            mType = type;
             mPendingIntent = null;
 
             try {
@@ -3779,6 +3757,16 @@
             }
         }
 
+        private String typeString() {
+            switch (mType) {
+                case LISTEN: return "Listen";
+                case REQUEST: return "Request";
+                case TRACK_DEFAULT: return "Track default";
+                default:
+                    return "unknown type";
+            }
+        }
+
         void unlinkDeathRecipient() {
             if (mBinder != null) {
                 mBinder.unlinkToDeath(this, 0);
@@ -3791,8 +3779,27 @@
             releaseNetworkRequest(request);
         }
 
+        /**
+         * Returns true iff. the contained NetworkRequest is one that:
+         *
+         *     - should be associated with at most one satisfying network
+         *       at a time;
+         *
+         *     - should cause a network to be kept up if it is the only network
+         *       which can satisfy the NetworkReqeust.
+         *
+         * For full detail of how isRequest() is used for pairing Networks with
+         * NetworkRequests read rematchNetworkAndRequests().
+         *
+         * TODO: Rename to something more properly descriptive.
+         */
+        public boolean isRequest() {
+            return (mType == NetworkRequestType.TRACK_DEFAULT) ||
+                   (mType == NetworkRequestType.REQUEST);
+        }
+
         public String toString() {
-            return (isRequest ? "Request" : "Listen") +
+            return typeString() +
                     " from uid/pid:" + mUid + "/" + mPid +
                     " for " + request +
                     (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
@@ -3845,10 +3852,13 @@
     @Override
     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
             Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
+        final NetworkRequestType type = (networkCapabilities == null)
+                ? NetworkRequestType.TRACK_DEFAULT
+                : NetworkRequestType.REQUEST;
         // If the requested networkCapabilities is null, take them instead from
         // the default network request. This allows callers to keep track of
         // the system default network.
-        if (networkCapabilities == null) {
+        if (type == NetworkRequestType.TRACK_DEFAULT) {
             networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities);
             enforceAccessPermission();
         } else {
@@ -3870,8 +3880,7 @@
 
         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
                 nextNetworkRequestId());
-        NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
-                NetworkRequestInfo.REQUEST);
+        NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder, type);
         if (DBG) log("requestNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
@@ -3936,7 +3945,7 @@
         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
                 nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
-                NetworkRequestInfo.REQUEST);
+                NetworkRequestType.REQUEST);
         if (DBG) log("pendingRequest for " + nri);
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
                 nri));
@@ -3988,7 +3997,7 @@
         NetworkRequest networkRequest = new NetworkRequest(
                 new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
-                NetworkRequestInfo.LISTEN);
+                NetworkRequestType.LISTEN);
         if (DBG) log("listenForNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -4006,7 +4015,7 @@
         NetworkRequest networkRequest = new NetworkRequest(
                 new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
-                NetworkRequestInfo.LISTEN);
+                NetworkRequestType.LISTEN);
         if (DBG) log("pendingListenForNetwork for " + nri);
 
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -4131,9 +4140,6 @@
         if (networkAgent.clatd != null) {
             networkAgent.clatd.fixupLinkProperties(oldLp);
         }
-        if (networkAgent.apfFilter != null) {
-            networkAgent.apfFilter.updateFilter();
-        }
 
         updateInterfaces(newLp, oldLp, netId);
         updateMtu(newLp, oldLp);
@@ -4457,6 +4463,7 @@
 
     private void makeDefault(NetworkAgentInfo newNetwork) {
         if (DBG) log("Switching to new default network: " + newNetwork);
+        ConnectivityServiceChangeEvent.logEvent(newNetwork.network.netId);
         setupDataActivityTracking(newNetwork);
         try {
             mNetd.setDefaultNetId(newNetwork.network.netId);
@@ -4523,7 +4530,7 @@
             // check if it satisfies the NetworkCapabilities
             if (VDBG) log("  checking if request is satisfied: " + nri.request);
             if (satisfies) {
-                if (!nri.isRequest) {
+                if (!nri.isRequest()) {
                     // This is not a request, it's a callback listener.
                     // Add it to newNetwork regardless of score.
                     if (newNetwork.addRequest(nri.request)) addedRequests.add(nri);
@@ -4583,7 +4590,7 @@
                     mNetworkForRequestId.remove(nri.request.requestId);
                     sendUpdatedScoreToFactories(nri.request, 0);
                 } else {
-                    if (nri.isRequest == true) {
+                    if (nri.isRequest()) {
                         Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
                                 newNetwork.name() +
                                 " without updating mNetworkForRequestId or factories!");
@@ -5087,5 +5094,4 @@
             NetworkAgentInfo nai, NetworkRequest defaultRequest) {
         return new NetworkMonitor(context, handler, nai, defaultRequest);
     }
-
 }
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index b57e14e..4749417 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -684,13 +684,18 @@
         public long SMS_TEMP_APP_WHITELIST_DURATION;
 
         private final ContentResolver mResolver;
+        private final boolean mHasWatch;
         private final KeyValueListParser mParser = new KeyValueListParser(',');
 
         public Constants(Handler handler, ContentResolver resolver) {
             super(handler);
             mResolver = resolver;
-            mResolver.registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS), false, this);
+            mHasWatch = getContext().getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_WATCH);
+            mResolver.registerContentObserver(Settings.Global.getUriFor(
+                    mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH
+                              : Settings.Global.DEVICE_IDLE_CONSTANTS),
+                    false, this);
             updateConstants();
         }
 
@@ -703,7 +708,8 @@
             synchronized (DeviceIdleController.this) {
                 try {
                     mParser.setString(Settings.Global.getString(mResolver,
-                            Settings.Global.DEVICE_IDLE_CONSTANTS));
+                            mHasWatch ? Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH
+                                      : Settings.Global.DEVICE_IDLE_CONSTANTS));
                 } catch (IllegalArgumentException e) {
                     // Failed to parse the settings string, log this and move on
                     // with defaults.
@@ -724,8 +730,9 @@
                 MIN_DEEP_MAINTENANCE_TIME = mParser.getLong(
                         KEY_MIN_DEEP_MAINTENANCE_TIME,
                         !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L);
+                long inactiveTimeoutDefault = (mHasWatch ? 15 : 30) * 60 * 1000L;
                 INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT,
-                        !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L);
+                        !COMPRESS_TIME ? inactiveTimeoutDefault : (inactiveTimeoutDefault / 10));
                 SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT,
                         !DEBUG ? 4 * 60 * 1000L : 60 * 1000L);
                 LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT,
@@ -733,8 +740,10 @@
                 LOCATION_ACCURACY = mParser.getFloat(KEY_LOCATION_ACCURACY, 20);
                 MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT,
                         !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
+                long idleAfterInactiveTimeout = (mHasWatch ? 15 : 30) * 60 * 1000L;
                 IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
-                        !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L);
+                        !COMPRESS_TIME ? idleAfterInactiveTimeout
+                                       : (idleAfterInactiveTimeout / 10));
                 IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_IDLE_PENDING_TIMEOUT,
                         !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L);
                 MAX_IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_PENDING_TIMEOUT,
diff --git a/services/core/java/com/android/server/GraphicsStatsService.java b/services/core/java/com/android/server/GraphicsStatsService.java
index 044bb04..e29515f 100644
--- a/services/core/java/com/android/server/GraphicsStatsService.java
+++ b/services/core/java/com/android/server/GraphicsStatsService.java
@@ -51,17 +51,15 @@
  * 2) ASHMEM_SIZE (for scratch space used during dumping)
  * 3) ASHMEM_SIZE * HISTORY_SIZE
  *
- * Currently ASHMEM_SIZE is 256 bytes and HISTORY_SIZE is 20. Assuming
- * the system then also has 10 active rendering processes in the worst case
- * this would end up using under 14KiB (12KiB for the buffers, plus some overhead
- * for userId, pid, package name, and a couple other objects)
+ * This is currently under 16KiB total memory in the worst case of
+ * 20 processes in history + 10 unique active processes.
  *
  *  @hide */
 public class GraphicsStatsService extends IGraphicsStats.Stub {
     public static final String GRAPHICS_STATS_SERVICE = "graphicsstats";
 
     private static final String TAG = "GraphicsStatsService";
-    private static final int ASHMEM_SIZE = 256;
+    private static final int ASHMEM_SIZE = 296;
     private static final int HISTORY_SIZE = 20;
 
     private final Context mContext;
diff --git a/services/core/java/com/android/server/HardwarePropertiesManagerService.java b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
index 575d99e..23cf64a 100644
--- a/services/core/java/com/android/server/HardwarePropertiesManagerService.java
+++ b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
@@ -23,6 +23,8 @@
 import android.os.CpuUsageInfo;
 import android.os.IHardwarePropertiesManager;
 import android.os.Process;
+import android.os.UserHandle;
+import com.android.server.vr.VrManagerInternal;
 
 import java.util.Arrays;
 
@@ -78,14 +80,15 @@
      *
      * @param callingPackage The calling package name.
      *
-     * @throws SecurityException if a non profile or device owner or system tries to retrieve
-     * information provided by the service.
+     * @throws SecurityException if something other than the profile or device owner, or the
+     *        current VR service tries to retrieve information provided by this service.
      */
     private void enforceHardwarePropertiesRetrievalAllowed(String callingPackage)
             throws SecurityException {
         final PackageManager pm = mContext.getPackageManager();
+        int uid = 0;
         try {
-            final int uid = pm.getPackageUid(callingPackage, 0);
+            uid = pm.getPackageUid(callingPackage, 0);
             if (Binder.getCallingUid() != uid) {
                 throw new SecurityException("The caller has faked the package name.");
             }
@@ -93,10 +96,13 @@
             throw new SecurityException("The caller has faked the package name.");
         }
 
+        final int userId = UserHandle.getUserId(uid);
+        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
         final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
         if (!dpm.isDeviceOwnerApp(callingPackage) && !dpm.isProfileOwnerApp(callingPackage)
-                && Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("The caller is not a device or profile owner or system.");
+                && !vrService.isCurrentVrListener(callingPackage, userId)) {
+            throw new SecurityException("The caller is not a device or profile owner or bound "
+                + "VrListenerService.");
         }
     }
 }
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 898d5b73..e042483 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -215,7 +215,7 @@
     // Ongoing notification
     private NotificationManager mNotificationManager;
     private KeyguardManager mKeyguardManager;
-    private StatusBarManagerService mStatusBar;
+    private @Nullable StatusBarManagerService mStatusBar;
     private Notification.Builder mImeSwitcherNotification;
     private PendingIntent mImeSwitchPendingIntent;
     private boolean mShowOngoingImeSwitcherForPhones;
@@ -1070,7 +1070,9 @@
                 mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
                 mNotificationManager = mContext.getSystemService(NotificationManager.class);
                 mStatusBar = statusBar;
-                statusBar.setIconVisibility(mSlotIme, false);
+                if (mStatusBar != null) {
+                    mStatusBar.setIconVisibility(mSlotIme, false);
+                }
                 updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition);
                 mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
                         com.android.internal.R.bool.show_ongoing_ime_switcher);
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 43d10c7..3fdcceb 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -779,11 +779,11 @@
             }
         }
 
-        if (hasNonDefaults) {
+        if (debug && hasNonDefaults) {
             if (dest.size() == 0) {
-                Slog.w(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT");
+                Slog.v(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT");
             } else if (dest.size() > 1) {
-                Slog.w(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT");
+                Slog.v(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT");
             }
         }
     }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 6fb0671..ed16af51 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -42,7 +42,10 @@
 
 import android.database.sqlite.SQLiteDatabase;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.storage.IMountService;
 import android.os.ServiceManager;
@@ -56,6 +59,7 @@
 import android.service.gatekeeper.GateKeeperResponse;
 import android.service.gatekeeper.IGateKeeperService;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.util.ArrayUtils;
@@ -70,6 +74,8 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Keeps the lock pattern/password data and related settings for each user.
@@ -590,11 +596,37 @@
     }
 
     private void unlockUser(int userId, byte[] token, byte[] secret) {
+        // TODO: make this method fully async so we can update UI with progress strings
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IProgressListener listener = new IProgressListener.Stub() {
+            @Override
+            public void onStarted(int id, Bundle extras) throws RemoteException {
+                // Ignored
+            }
+
+            @Override
+            public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
+                // Ignored
+            }
+
+            @Override
+            public void onFinished(int id, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser finished!");
+                latch.countDown();
+            }
+        };
+
         try {
-            ActivityManagerNative.getDefault().unlockUser(userId, token, secret);
+            ActivityManagerNative.getDefault().unlockUser(userId, token, secret, listener);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
+
+        try {
+            latch.await(15, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
     }
 
     private byte[] getCurrentHandle(int userId) {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index ccca5ba..45008dc 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -2912,36 +2912,57 @@
     @Override
     public StorageVolume[] getVolumeList(int uid, String packageName, int flags) {
         final int userId = UserHandle.getUserId(uid);
+
         final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0;
+        final boolean realState = (flags & StorageManager.FLAG_REAL_STATE) != 0;
+        final boolean includeInvisible = (flags & StorageManager.FLAG_INCLUDE_INVISIBLE) != 0;
 
-        boolean reportUnmounted = false;
-        boolean foundPrimary = false;
-
-        final long identity = Binder.clearCallingIdentity();
+        final boolean userKeyUnlocked;
+        final boolean storagePermission;
+        final long token = Binder.clearCallingIdentity();
         try {
-            if (!mMountServiceInternal.hasExternalStorage(uid, packageName)) {
-                reportUnmounted = true;
-            }
-            if (!isUserKeyUnlocked(userId)) {
-                reportUnmounted = true;
-            }
+            userKeyUnlocked = isUserKeyUnlocked(userId);
+            storagePermission = mMountServiceInternal.hasExternalStorage(uid, packageName);
         } finally {
-            Binder.restoreCallingIdentity(identity);
+            Binder.restoreCallingIdentity(token);
         }
 
+        boolean foundPrimary = false;
+
         final ArrayList<StorageVolume> res = new ArrayList<>();
         synchronized (mLock) {
             for (int i = 0; i < mVolumes.size(); i++) {
                 final VolumeInfo vol = mVolumes.valueAt(i);
-                if (forWrite ? vol.isVisibleForWrite(userId) : vol.isVisibleForRead(userId)) {
-                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
-                            reportUnmounted);
-                    if (vol.isPrimary()) {
-                        res.add(0, userVol);
-                        foundPrimary = true;
-                    } else {
-                        res.add(userVol);
-                    }
+                switch (vol.getType()) {
+                    case VolumeInfo.TYPE_PUBLIC:
+                    case VolumeInfo.TYPE_EMULATED:
+                        break;
+                    default:
+                        continue;
+                }
+
+                boolean match = false;
+                if (forWrite) {
+                    match = vol.isVisibleForWrite(userId);
+                } else {
+                    match = vol.isVisibleForRead(userId) || includeInvisible;
+                }
+                if (!match) continue;
+
+                boolean reportUnmounted = false;
+                if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
+                    reportUnmounted = true;
+                } else if (!storagePermission && !realState) {
+                    reportUnmounted = true;
+                }
+
+                final StorageVolume userVol = vol.buildStorageVolume(mContext, userId,
+                        reportUnmounted);
+                if (vol.isPrimary()) {
+                    res.add(0, userVol);
+                    foundPrimary = true;
+                } else {
+                    res.add(userVol);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 548b662..c6d536d 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -209,9 +209,12 @@
     /** Set of interfaces with active alerts. */
     @GuardedBy("mQuotaLock")
     private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
-    /** Set of UIDs with active reject rules. */
+    /** Set of UIDs blacklisted on metered networks. */
     @GuardedBy("mQuotaLock")
-    private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
+    private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
+    /** Set of UIDs whitelisted on metered networks. */
+    @GuardedBy("mQuotaLock")
+    private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
     /** Set of UIDs with cleartext penalties. */
     @GuardedBy("mQuotaLock")
     private SparseIntArray mUidCleartextPolicy = new SparseIntArray();
@@ -240,6 +243,9 @@
     @GuardedBy("mQuotaLock")
     final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
 
+    @GuardedBy("mQuotaLock")
+    private boolean mDataSaverMode;
+
     private Object mIdleTimerLock = new Object();
     /** Set of interfaces with active idle timers. */
     private static class IdleTimerParams {
@@ -513,6 +519,28 @@
         }
     }
 
+    // Sync the state of the given chain with the native daemon.
+    private void syncFirewallChainLocked(int chain, SparseIntArray uidFirewallRules, String name) {
+        int size = uidFirewallRules.size();
+        if (size > 0) {
+            // Make a copy of the current rules, and then clear them. This is because
+            // setFirewallUidRuleInternal only pushes down rules to the native daemon if they are
+            // different from the current rules stored in the mUidFirewall*Rules array for the
+            // specified chain. If we don't clear the rules, setFirewallUidRuleInternal will do
+            // nothing.
+            final SparseIntArray rules = uidFirewallRules.clone();
+            uidFirewallRules.clear();
+
+            // Now push the rules. setFirewallUidRuleInternal will push each of these down to the
+            // native daemon, and also add them to the mUidFirewall*Rules array for the specified
+            // chain.
+            if (DBG) Slog.d(TAG, "Pushing " + size + " active firewall " + name + "UID rules");
+            for (int i = 0; i < rules.size(); i++) {
+                setFirewallUidRuleInternal(chain, rules.keyAt(i), rules.valueAt(i));
+            }
+        }
+    }
+
     /**
      * Prepare native daemon once connected, enabling modules and pushing any
      * existing in-memory rules.
@@ -561,6 +589,9 @@
 
         // push any existing quota or UID rules
         synchronized (mQuotaLock) {
+
+            setDataSaverModeEnabled(mDataSaverMode);
+
             int size = mActiveQuotas.size();
             if (size > 0) {
                 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules");
@@ -581,13 +612,25 @@
                 }
             }
 
-            size = mUidRejectOnQuota.size();
+            size = mUidRejectOnMetered.size();
             if (size > 0) {
-                if (DBG) Slog.d(TAG, "Pushing " + size + " active UID rules");
-                final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota;
-                mUidRejectOnQuota = new SparseBooleanArray();
+                if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules");
+                final SparseBooleanArray uidRejectOnQuota = mUidRejectOnMetered;
+                mUidRejectOnMetered = new SparseBooleanArray();
                 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
-                    setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i));
+                    setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i),
+                            uidRejectOnQuota.valueAt(i));
+                }
+            }
+
+            size = mUidAllowOnMetered.size();
+            if (size > 0) {
+                if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules");
+                final SparseBooleanArray uidAcceptOnQuota = mUidAllowOnMetered;
+                mUidAllowOnMetered = new SparseBooleanArray();
+                for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
+                    setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i),
+                            uidAcceptOnQuota.valueAt(i));
                 }
             }
 
@@ -603,55 +646,18 @@
 
             setFirewallEnabled(mFirewallEnabled || LockdownVpnTracker.isEnabled());
 
-            size = mUidFirewallRules.size();
-            if (size > 0) {
-                if (DBG) Slog.d(TAG, "Pushing " + size + " active firewall UID rules");
-                final SparseIntArray uidFirewallRules = mUidFirewallRules;
-                mUidFirewallRules = new SparseIntArray();
-                for (int i = 0; i < uidFirewallRules.size(); i++) {
-                    setFirewallUidRuleInternal(FIREWALL_CHAIN_NONE, uidFirewallRules.keyAt(i),
-                            uidFirewallRules.valueAt(i));
-                }
-            }
+            syncFirewallChainLocked(FIREWALL_CHAIN_NONE, mUidFirewallRules, "");
+            syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, mUidFirewallStandbyRules, "standby ");
+            syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mUidFirewallDozableRules, "dozable ");
+            syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, mUidFirewallPowerSaveRules,
+                    "powersave ");
 
-            size = mUidFirewallStandbyRules.size();
-            if (size > 0) {
-                if (DBG) Slog.d(TAG, "Pushing " + size + " active firewall standby UID rules");
-                final SparseIntArray uidFirewallRules = mUidFirewallStandbyRules;
-                mUidFirewallStandbyRules = new SparseIntArray();
-                for (int i = 0; i < uidFirewallRules.size(); i++) {
-                    setFirewallUidRuleInternal(FIREWALL_CHAIN_STANDBY, uidFirewallRules.keyAt(i),
-                            uidFirewallRules.valueAt(i));
-                }
-            }
             if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)) {
                 setFirewallChainEnabled(FIREWALL_CHAIN_STANDBY, true);
             }
-
-            size = mUidFirewallDozableRules.size();
-            if (size > 0) {
-                if (DBG) Slog.d(TAG, "Pushing " + size + " active firewall dozable UID rules");
-                final SparseIntArray uidFirewallRules = mUidFirewallDozableRules;
-                mUidFirewallDozableRules = new SparseIntArray();
-                for (int i = 0; i < uidFirewallRules.size(); i++) {
-                    setFirewallUidRuleInternal(FIREWALL_CHAIN_DOZABLE, uidFirewallRules.keyAt(i),
-                            uidFirewallRules.valueAt(i));
-                }
-            }
             if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)) {
                 setFirewallChainEnabled(FIREWALL_CHAIN_DOZABLE, true);
             }
-
-            size = mUidFirewallPowerSaveRules.size();
-            if (size > 0) {
-                Slog.d(TAG, "Pushing " + size + " active firewall powersave UID rules");
-                final SparseIntArray uidFirewallRules = mUidFirewallPowerSaveRules;
-                mUidFirewallPowerSaveRules = new SparseIntArray();
-                for (int i = 0; i < uidFirewallRules.size(); i++) {
-                    setFirewallUidRuleInternal(FIREWALL_CHAIN_POWERSAVE, uidFirewallRules.keyAt(i),
-                            uidFirewallRules.valueAt(i));
-                }
-            }
             if (mFirewallChainStates.get(FIREWALL_CHAIN_POWERSAVE)) {
                 setFirewallChainEnabled(FIREWALL_CHAIN_POWERSAVE, true);
             }
@@ -738,6 +744,7 @@
     private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks {
         @Override
         public void onDaemonConnected() {
+            Slog.i(TAG, "onDaemonConnected()");
             // event is dispatched from internal NDC thread, so we prepare the
             // daemon back on main thread.
             if (mConnectedSignal != null) {
@@ -1698,28 +1705,30 @@
         }
     }
 
-    @Override
-    public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
+    private void setUidOnMeteredNetworkList(SparseBooleanArray quotaList, int uid,
+            boolean blacklist, boolean enable) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         // silently discard when control disabled
         // TODO: eventually migrate to be always enabled
         if (!mBandwidthControlEnabled) return;
 
+        final String chain = blacklist ? "naughtyapps" : "niceapps";
+        final String suffix = enable ? "add" : "remove";
+
         synchronized (mQuotaLock) {
-            final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
-            if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
+            final boolean oldEnable = quotaList.get(uid, false);
+            if (oldEnable == enable) {
                 // TODO: eventually consider throwing
                 return;
             }
 
             try {
-                mConnector.execute("bandwidth",
-                        rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid);
-                if (rejectOnQuotaInterfaces) {
-                    mUidRejectOnQuota.put(uid, true);
+                mConnector.execute("bandwidth", suffix + chain, uid);
+                if (enable) {
+                    quotaList.put(uid, true);
                 } else {
-                    mUidRejectOnQuota.delete(uid);
+                    quotaList.delete(uid);
                 }
             } catch (NativeDaemonConnectorException e) {
                 throw e.rethrowAsParcelableException();
@@ -1728,6 +1737,39 @@
     }
 
     @Override
+    public void setUidMeteredNetworkBlacklist(int uid, boolean enable) {
+        setUidOnMeteredNetworkList(mUidRejectOnMetered, uid, true, enable);
+    }
+
+    @Override
+    public void setUidMeteredNetworkWhitelist(int uid, boolean enable) {
+        setUidOnMeteredNetworkList(mUidAllowOnMetered, uid, false, enable);
+    }
+
+    @Override
+    public boolean setDataSaverModeEnabled(boolean enable) {
+        if (DBG) Log.d(TAG, "setDataSaverMode: " + enable);
+        synchronized (mQuotaLock) {
+            if (mDataSaverMode == enable) {
+                Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode);
+                return true;
+            }
+            try {
+                final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
+                if (changed) {
+                    mDataSaverMode = enable;
+                } else {
+                    Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed");
+                }
+                return changed;
+            } catch (RemoteException e) {
+                Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e);
+                return false;
+            }
+        }
+    }
+
+    @Override
     public void setUidCleartextNetworkPolicy(int uid, int policy) {
         if (Binder.getCallingUid() != uid) {
             mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
@@ -2221,29 +2263,22 @@
         synchronized (mQuotaLock) {
             pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
             pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
-        }
-
-        synchronized (mUidRejectOnQuota) {
-            pw.print("UID reject on quota ifaces: [");
-            final int size = mUidRejectOnQuota.size();
-            for (int i = 0; i < size; i++) {
-                pw.print(mUidRejectOnQuota.keyAt(i));
-                if (i < size - 1) pw.print(",");
-            }
-            pw.println("]");
+            pw.print("Data saver mode: "); pw.println(mDataSaverMode);
+            dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered);
+            dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered);
         }
 
         synchronized (mUidFirewallRules) {
             dumpUidFirewallRule(pw, "", mUidFirewallRules);
         }
 
-        pw.println("UID firewall standby chain enabled: " +
+        pw.print("UID firewall standby chain enabled: "); pw.println(
                 mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY));
         synchronized (mUidFirewallStandbyRules) {
             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
         }
 
-        pw.println("UID firewall dozable chain enabled: " +
+        pw.print("UID firewall dozable chain enabled: "); pw.println(
                 mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE));
         synchronized (mUidFirewallDozableRules) {
             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
@@ -2267,6 +2302,29 @@
         }
 
         pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
+        pw.print("Netd service status: " );
+        if (mNetdService == null) {
+            pw.println("disconnected");
+        } else {
+            try {
+                final boolean alive = mNetdService.isAlive();
+                pw.println(alive ? "alive": "dead");
+            } catch (RemoteException e) {
+                pw.println("unreachable");
+            }
+        }
+    }
+
+    private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) {
+        pw.print("UID bandwith control ");
+        pw.print(name);
+        pw.print(" rule: [");
+        final int size = list.size();
+        for (int i = 0; i < size; i++) {
+            pw.print(list.keyAt(i));
+            if (i < size - 1) pw.print(",");
+        }
+        pw.println("]");
     }
 
     private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) {
diff --git a/services/core/java/com/android/server/RecoverySystemService.java b/services/core/java/com/android/server/RecoverySystemService.java
index d284d07..276687f 100644
--- a/services/core/java/com/android/server/RecoverySystemService.java
+++ b/services/core/java/com/android/server/RecoverySystemService.java
@@ -79,7 +79,7 @@
                 uncryptFile.write(filename + "\n");
             } catch (IOException e) {
                 Slog.e(TAG, "IOException when writing \"" + RecoverySystem.UNCRYPT_PACKAGE_FILE +
-                        "\": " + e.getMessage());
+                        "\": ", e);
                 return false;
             }
 
@@ -94,8 +94,11 @@
             }
 
             // Read the status from the socket.
-            try (DataInputStream dis = new DataInputStream(socket.getInputStream());
-                    DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
+            DataInputStream dis = null;
+            DataOutputStream dos = null;
+            try {
+                dis = new DataInputStream(socket.getInputStream());
+                dos = new DataOutputStream(socket.getOutputStream());
                 int lastStatus = Integer.MIN_VALUE;
                 while (true) {
                     int status = dis.readInt();
@@ -111,7 +114,7 @@
                         if (listener != null) {
                             try {
                                 listener.onProgress(status);
-                            } catch (RemoteException unused) {
+                            } catch (RemoteException ignored) {
                                 Slog.w(TAG, "RemoteException when posting progress");
                             }
                         }
@@ -121,7 +124,6 @@
                             // waits for the ack so the socket won't be
                             // destroyed before we receive the code.
                             dos.writeInt(0);
-                            dos.flush();
                             break;
                         }
                     } else {
@@ -131,14 +133,15 @@
                         // for the ack so the socket won't be destroyed before
                         // we receive the code.
                         dos.writeInt(0);
-                        dos.flush();
                         return false;
                     }
                 }
             } catch (IOException e) {
-                Slog.e(TAG, "IOException when reading status: " + e);
+                Slog.e(TAG, "IOException when reading status: ", e);
                 return false;
             } finally {
+                IoUtils.closeQuietly(dis);
+                IoUtils.closeQuietly(dos);
                 IoUtils.closeQuietly(socket);
             }
 
@@ -169,11 +172,11 @@
                             LocalSocketAddress.Namespace.RESERVED));
                     done = true;
                     break;
-                } catch (IOException unused) {
+                } catch (IOException ignored) {
                     try {
                         Thread.sleep(1000);
                     } catch (InterruptedException e) {
-                        Slog.w(TAG, "Interrupted: " + e);
+                        Slog.w(TAG, "Interrupted: ", e);
                     }
                 }
             }
@@ -200,8 +203,12 @@
                 return false;
             }
 
-            try (DataInputStream dis = new DataInputStream(socket.getInputStream());
-                    DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
+            DataInputStream dis = null;
+            DataOutputStream dos = null;
+            try {
+                dis = new DataInputStream(socket.getInputStream());
+                dos = new DataOutputStream(socket.getOutputStream());
+
                 // Send the BCB commands if it's to setup BCB.
                 if (isSetup) {
                     dos.writeInt(command.length());
@@ -215,7 +222,6 @@
                 // Ack receipt of the status code. uncrypt waits for the ack so
                 // the socket won't be destroyed before we receive the code.
                 dos.writeInt(0);
-                dos.flush();
 
                 if (status == 100) {
                     Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear") +
@@ -226,9 +232,11 @@
                     return false;
                 }
             } catch (IOException e) {
-                Slog.e(TAG, "IOException when getting output stream: " + e);
+                Slog.e(TAG, "IOException when communicating with uncrypt: ", e);
                 return false;
             } finally {
+                IoUtils.closeQuietly(dis);
+                IoUtils.closeQuietly(dos);
                 IoUtils.closeQuietly(socket);
             }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c1ec71c..9070849 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -40,6 +40,7 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.MemInfoReader;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.ProgressReporter;
 import com.android.server.AppOpsService;
 import com.android.server.AttributeCache;
 import com.android.server.DeviceIdleController;
@@ -55,7 +56,6 @@
 import com.android.server.pm.Installer;
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.vr.VrManagerInternal;
-import com.android.server.wm.AppTransition;
 import com.android.server.wm.WindowManagerService;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -103,7 +103,6 @@
 import android.app.ProfilerInfo;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
-import android.app.admin.IDevicePolicyManager;
 import android.app.assist.AssistContent;
 import android.app.assist.AssistStructure;
 import android.app.backup.IBackupManager;
@@ -167,6 +166,7 @@
 import android.os.IBinder;
 import android.os.IPermissionController;
 import android.os.IProcessInfoService;
+import android.os.IProgressListener;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
@@ -216,10 +216,6 @@
 import android.view.View;
 import android.view.WindowManager;
 
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -355,6 +351,7 @@
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
+import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
@@ -364,9 +361,6 @@
 public final class ActivityManagerService extends ActivityManagerNative
         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
-    // File that stores last updated system version and called preboot receivers
-    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
-
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
@@ -501,8 +495,6 @@
     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
     static final int ALLOW_FULL_ONLY = 2;
 
-    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
-
     // Delay in notifying task stack change listeners (in millis)
     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
 
@@ -526,6 +518,7 @@
 
     // Determines whether to take full screen screenshots
     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
+    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
 
     private static native int nativeMigrateToBoost();
     private static native int nativeMigrateFromBoost();
@@ -1112,8 +1105,6 @@
     boolean mBooting = false;
     boolean mCallFinishBooting = false;
     boolean mBootAnimationComplete = false;
-    boolean mWaitingUpdate = false;
-    boolean mDidUpdate = false;
     boolean mOnBattery = false;
     boolean mLaunchWarningShown = false;
 
@@ -1470,6 +1461,7 @@
     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
+    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1491,6 +1483,7 @@
     /** The dimensions of the thumbnails in the Recents UI. */
     int mThumbnailWidth;
     int mThumbnailHeight;
+    float mFullscreenThumbnailScale;
 
     final ServiceThread mHandlerThread;
     final MainHandler mHandler;
@@ -2017,6 +2010,21 @@
                 }
                 break;
             }
+            case NOTIFY_FORCED_RESIZABLE_MSG: {
+                synchronized (ActivityManagerService.this) {
+                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
+                        try {
+                            // Make a one-way callback to the listener
+                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
+                                    (String) msg.obj, msg.arg1);
+                        } catch (RemoteException e){
+                            // Handled by the RemoteCallbackList
+                        }
+                    }
+                    mTaskStackListeners.finishBroadcast();
+                }
+                break;
+            }
             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
                 final int uid = msg.arg1;
                 final byte[] firstPacket = (byte[]) msg.obj;
@@ -3013,7 +3021,7 @@
             if (!app.killed) {
                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
                 Process.killProcessQuiet(app.pid);
-                killProcessGroup(app.info.uid, app.pid);
+                killProcessGroup(app.uid, app.pid);
             }
             if (lrui <= mLruProcessActivityStart) {
                 mLruProcessActivityStart--;
@@ -3386,7 +3394,7 @@
             // clean it up now.
             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
             checkTime(startTime, "startProcess: bad proc running, killing");
-            killProcessGroup(app.info.uid, app.pid);
+            killProcessGroup(app.uid, app.pid);
             handleAppDiedLocked(app, true, true);
             checkTime(startTime, "startProcess: done killing old proc");
         }
@@ -4477,63 +4485,14 @@
         }
         final long origId = Binder.clearCallingIdentity();
         try {
-            return startActivityFromRecentsInner(taskId, bOptions);
+            synchronized (this) {
+                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
+            }
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
     }
 
-    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
-        final TaskRecord task;
-        final int callingUid;
-        final String callingPackage;
-        final Intent intent;
-        final int userId;
-        synchronized (this) {
-            final ActivityOptions activityOptions = (bOptions != null)
-                    ? new ActivityOptions(bOptions) : null;
-            final int launchStackId = (activityOptions != null)
-                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
-
-            if (launchStackId == HOME_STACK_ID) {
-                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
-                        + taskId + " can't be launch in the home stack.");
-            }
-            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
-            if (task == null) {
-                throw new IllegalArgumentException(
-                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
-            }
-
-            if (launchStackId != INVALID_STACK_ID) {
-                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
-                    mWindowManager.setDockedStackCreateState(
-                            activityOptions.getDockCreateMode(), null /* initialBounds */);
-                }
-                if (task.stack.mStackId != launchStackId) {
-                    mStackSupervisor.moveTaskToStackLocked(
-                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
-                            ANIMATE);
-                }
-            }
-
-            // If the user must confirm credentials (e.g. when first launching a work app and the
-            // Work Challenge is present) let startActivityInPackage handle the intercepting.
-            if (!mUserController.shouldConfirmCredentials(task.userId)
-                    && task.getRootActivity() != null) {
-                moveTaskToFrontLocked(task.taskId, 0, bOptions);
-                return ActivityManager.START_TASK_TO_FRONT;
-            }
-            callingUid = task.mCallingUid;
-            callingPackage = task.mCallingPackage;
-            intent = task.intent;
-            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
-            userId = task.userId;
-        }
-        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
-                bOptions, userId, null, task);
-    }
-
     final int startActivityInPackage(int uid, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
@@ -5021,7 +4980,7 @@
             if (!fromBinderDied) {
                 Process.killProcessQuiet(pid);
             }
-            killProcessGroup(app.info.uid, pid);
+            killProcessGroup(app.uid, pid);
             app.killed = true;
         }
 
@@ -6260,6 +6219,7 @@
         app.debugging = false;
         app.cached = false;
         app.killedByAm = false;
+        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
 
         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
 
@@ -10383,7 +10343,7 @@
                 }
                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
 
-                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
+                if (!mProcessesReady
                         && !cpi.processName.equals("system")) {
                     // If this content provider does not run in the system
                     // process, and the system is not yet ready to run other
@@ -10974,7 +10934,7 @@
                 final int NA = apps.size();
                 for (int ia = 0; ia < NA; ia++) {
                     final ProcessRecord app = apps.valueAt(ia);
-                    if (app.userId != userId || app.thread == null) continue;
+                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
 
                     final int NG = app.pkgList.size();
                     for (int ig = 0; ig < NG; ig++) {
@@ -11422,18 +11382,18 @@
                 try {
                     final int currentUserId = mUserController.getCurrentUserIdLocked();
                     // Get the focused task before launching launcher.
-                    final int taskId = (mFocusedActivity == null)
-                            ? -1 : mFocusedActivity.task.taskId;
-                    startHomeActivityLocked(currentUserId, "notifyLockedProfile");
+
                     if (mUserController.isLockScreenDisabled(currentUserId)) {
-                        // If there is no device lock, we first go to launcher and then resume the
-                        // original task. Work challenge will be shown because we intercepted
-                        // startActivityFromRecentsInner and the reason why we switch to home stack
-                        // first is to prevent pressing back button brings user back to the work
-                        // app.
-                        if (taskId != -1) {
-                            startActivityFromRecentsInner(taskId, null);
+
+                        // If there is no device lock, we will show the profile's credential page.
+                        // startActivityFromRecentsInner is intercepted and will forward user to it.
+                        if (mFocusedActivity != null) {
+                            mStackSupervisor.startActivityFromRecentsInner(
+                                    mFocusedActivity.task.taskId, null);
                         }
+                    } else {
+                        // Showing launcher to avoid user entering credential twice.
+                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
@@ -12592,6 +12552,8 @@
                     com.android.internal.R.dimen.thumbnail_width);
             mThumbnailHeight = res.getDimensionPixelSize(
                     com.android.internal.R.dimen.thumbnail_height);
+            mFullscreenThumbnailScale = res.getFraction(
+                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
@@ -12604,187 +12566,6 @@
         return mSystemReady;
     }
 
-    private static File getCalledPreBootReceiversFile() {
-        File dataDir = Environment.getDataDirectory();
-        File systemDir = new File(dataDir, "system");
-        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
-        return fname;
-    }
-
-    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
-        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
-        File file = getCalledPreBootReceiversFile();
-        FileInputStream fis = null;
-        try {
-            fis = new FileInputStream(file);
-            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
-            int fvers = dis.readInt();
-            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
-                String vers = dis.readUTF();
-                String codename = dis.readUTF();
-                String build = dis.readUTF();
-                if (android.os.Build.VERSION.RELEASE.equals(vers)
-                        && android.os.Build.VERSION.CODENAME.equals(codename)
-                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
-                    int num = dis.readInt();
-                    while (num > 0) {
-                        num--;
-                        String pkg = dis.readUTF();
-                        String cls = dis.readUTF();
-                        lastDoneReceivers.add(new ComponentName(pkg, cls));
-                    }
-                }
-            }
-        } catch (FileNotFoundException e) {
-        } catch (IOException e) {
-            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
-        } finally {
-            if (fis != null) {
-                try {
-                    fis.close();
-                } catch (IOException e) {
-                }
-            }
-        }
-        return lastDoneReceivers;
-    }
-
-    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
-        File file = getCalledPreBootReceiversFile();
-        FileOutputStream fos = null;
-        DataOutputStream dos = null;
-        try {
-            fos = new FileOutputStream(file);
-            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
-            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
-            dos.writeUTF(android.os.Build.VERSION.RELEASE);
-            dos.writeUTF(android.os.Build.VERSION.CODENAME);
-            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
-            dos.writeInt(list.size());
-            for (int i=0; i<list.size(); i++) {
-                dos.writeUTF(list.get(i).getPackageName());
-                dos.writeUTF(list.get(i).getClassName());
-            }
-        } catch (IOException e) {
-            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
-            file.delete();
-        } finally {
-            FileUtils.sync(fos);
-            if (dos != null) {
-                try {
-                    dos.close();
-                } catch (IOException e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    final class PreBootContinuation extends IIntentReceiver.Stub {
-        final Intent intent;
-        final Runnable onFinishCallback;
-        final ArrayList<ComponentName> doneReceivers;
-        final List<ResolveInfo> ris;
-        final int[] users;
-        int lastRi = -1;
-        int curRi = 0;
-        int curUser = 0;
-
-        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
-                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
-            intent = _intent;
-            onFinishCallback = _onFinishCallback;
-            doneReceivers = _doneReceivers;
-            ris = _ris;
-            users = _users;
-        }
-
-        void go() {
-            if (lastRi != curRi) {
-                ActivityInfo ai = ris.get(curRi).activityInfo;
-                ComponentName comp = new ComponentName(ai.packageName, ai.name);
-                intent.setComponent(comp);
-                doneReceivers.add(comp);
-                lastRi = curRi;
-                CharSequence label = ai.loadLabel(mContext.getPackageManager());
-                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
-            }
-            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
-                    + " for user " + users[curUser]);
-            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
-            broadcastIntentLocked(null, null, intent, null, this,
-                    0, null, null, null, AppOpsManager.OP_NONE,
-                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
-        }
-
-        public void performReceive(Intent intent, int resultCode,
-                String data, Bundle extras, boolean ordered,
-                boolean sticky, int sendingUser) {
-            curUser++;
-            if (curUser >= users.length) {
-                curUser = 0;
-                curRi++;
-                if (curRi >= ris.size()) {
-                    // All done sending broadcasts!
-                    if (onFinishCallback != null) {
-                        // The raw IIntentReceiver interface is called
-                        // with the AM lock held, so redispatch to
-                        // execute our code without the lock.
-                        mHandler.post(onFinishCallback);
-                    }
-                    return;
-                }
-            }
-            go();
-        }
-    }
-
-    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
-            ArrayList<ComponentName> doneReceivers) {
-        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
-        List<ResolveInfo> ris = null;
-        try {
-            ris = AppGlobals.getPackageManager().queryIntentReceivers(
-                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).getList();
-        } catch (RemoteException e) {
-        }
-        if (ris == null) {
-            return false;
-        }
-        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
-
-        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
-        for (int i=0; i<ris.size(); i++) {
-            ActivityInfo ai = ris.get(i).activityInfo;
-            ComponentName comp = new ComponentName(ai.packageName, ai.name);
-            if (lastDoneReceivers.contains(comp)) {
-                // We already did the pre boot receiver for this app with the current
-                // platform version, so don't do it again...
-                ris.remove(i);
-                i--;
-                // ...however, do keep it as one that has been done, so we don't
-                // forget about it when rewriting the file of last done receivers.
-                doneReceivers.add(comp);
-            }
-        }
-
-        if (ris.size() <= 0) {
-            return false;
-        }
-
-        // TODO: can we still do this with per user encryption?
-        final int[] users = mUserController.getUsers();
-        if (users.length <= 0) {
-            return false;
-        }
-
-        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
-                ris, users);
-        cont.go();
-        return true;
-    }
-
     public void systemReady(final Runnable goingCallback) {
         synchronized(this) {
             if (mSystemReady) {
@@ -12801,33 +12582,7 @@
 
             // Make sure we have the current profile info, since it is needed for security checks.
             mUserController.onSystemReady();
-
             mRecentTasks.onSystemReadyLocked();
-            // Check to see if there are any update receivers to run.
-            if (!mDidUpdate) {
-                if (mWaitingUpdate) {
-                    return;
-                }
-                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
-                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
-                    public void run() {
-                        synchronized (ActivityManagerService.this) {
-                            mDidUpdate = true;
-                        }
-                        showBootMessage(mContext.getText(
-                                R.string.android_upgrading_complete),
-                                false);
-                        writeLastDonePreBootReceivers(doneReceivers);
-                        systemReady(goingCallback);
-                    }
-                }, doneReceivers);
-
-                if (mWaitingUpdate) {
-                    return;
-                }
-                mDidUpdate = true;
-            }
-
             mAppOpsService.systemReady();
             mSystemReady = true;
         }
@@ -18607,9 +18362,14 @@
             for (int j = 0; j < activitiesSize; j++) {
                 final ActivityRecord r = app.activities.get(j);
                 if (r.app != app) {
-                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
-                            + app + "?!? Using " + r.app + " instead.");
-                    continue;
+                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
+                            + " instead of expected " + app);
+                    if (r.app == null || (r.app.uid == app.uid)) {
+                        // Only fix things up when they look sane
+                        r.app = app;
+                    } else {
+                        continue;
+                    }
                 }
                 if (r.visible) {
                     // App has a visible activity; only upgrade adjustment.
@@ -20755,8 +20515,8 @@
     }
 
     @Override
-    public boolean unlockUser(int userId, byte[] token, byte[] secret) {
-        return mUserController.unlockUser(userId, token, secret);
+    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
+        return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
     }
 
     @Override
@@ -21031,6 +20791,20 @@
                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
             }
         }
+
+        @Override
+        public void notifyAppTransitionFinished() {
+            synchronized (ActivityManagerService.this) {
+                mStackSupervisor.notifyAppTransitionDone();
+            }
+        }
+
+        @Override
+        public void notifyAppTransitionCancelled() {
+            synchronized (ActivityManagerService.this) {
+                mStackSupervisor.notifyAppTransitionDone();
+            }
+        }
     }
 
     private final class SleepTokenImpl extends SleepToken {
@@ -21119,7 +20893,9 @@
             // Will bring task to front if it already has a root activity.
             final long origId = Binder.clearCallingIdentity();
             try {
-                startActivityFromRecentsInner(mTaskId, null);
+                synchronized (this) {
+                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
+                }
             } finally {
                 Binder.restoreCallingIdentity(origId);
             }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 26eaa8a..e4ffde2 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -258,6 +258,12 @@
     // Current bounds of the stack or null if fullscreen.
     Rect mBounds = null;
 
+    boolean mUpdateBoundsDeferred;
+    boolean mUpdateBoundsDeferredCalled;
+    final Rect mDeferredBounds = new Rect();
+    final Rect mDeferredTaskBounds = new Rect();
+    final Rect mDeferredTaskInsetBounds = new Rect();
+
     long mLaunchStartTime = 0;
     long mFullyDrawnStartTime = 0;
 
@@ -427,6 +433,57 @@
         mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
     }
 
+    /**
+     * Defers updating the bounds of the stack. If the stack was resized/repositioned while
+     * deferring, the bounds will update in {@link #continueUpdateBounds()}.
+     */
+    void deferUpdateBounds() {
+        if (!mUpdateBoundsDeferred) {
+            mUpdateBoundsDeferred = true;
+            mUpdateBoundsDeferredCalled = false;
+        }
+    }
+
+    /**
+     * Continues updating bounds after updates have been deferred. If there was a resize attempt
+     * between {@link #deferUpdateBounds()} and {@link #continueUpdateBounds()}, the stack will
+     * be resized to that bounds.
+     */
+    void continueUpdateBounds() {
+        final boolean wasDeferred = mUpdateBoundsDeferred;
+        mUpdateBoundsDeferred = false;
+        if (wasDeferred && mUpdateBoundsDeferredCalled) {
+            mStackSupervisor.resizeStackUncheckedLocked(this,
+                    mDeferredBounds.isEmpty() ? null : mDeferredBounds,
+                    mDeferredTaskBounds.isEmpty() ? null : mDeferredTaskBounds,
+                    mDeferredTaskInsetBounds.isEmpty() ? null : mDeferredTaskInsetBounds);
+        }
+    }
+
+    boolean updateBoundsAllowed(Rect bounds, Rect tempTaskBounds,
+            Rect tempTaskInsetBounds) {
+        if (!mUpdateBoundsDeferred) {
+            return true;
+        }
+        if (bounds != null) {
+            mDeferredBounds.set(bounds);
+        } else {
+            mDeferredBounds.setEmpty();
+        }
+        if (tempTaskBounds != null) {
+            mDeferredTaskBounds.set(tempTaskBounds);
+        } else {
+            mDeferredTaskBounds.setEmpty();
+        }
+        if (tempTaskInsetBounds != null) {
+            mDeferredTaskInsetBounds.set(tempTaskInsetBounds);
+        } else {
+            mDeferredTaskInsetBounds.setEmpty();
+        }
+        mUpdateBoundsDeferredCalled = true;
+        return false;
+    }
+
     void setBounds(Rect bounds) {
         mBounds = mFullscreen ? null : new Rect(bounds);
         if (mTaskPositioner != null) {
@@ -929,7 +986,7 @@
             // use within SystemUI while keeping memory usage low.
             if (ActivityManagerService.TAKE_FULLSCREEN_SCREENSHOTS) {
                 w = h = -1;
-                scale = 0.5f;
+                scale = mService.mFullscreenThumbnailScale;
             }
             return mWindowManager.screenshotApplications(who.appToken, Display.DEFAULT_DISPLAY,
                     w, h, scale);
@@ -1980,7 +2037,9 @@
         if (next == null) {
             // There are no more activities!
             final String reason = "noMoreActivities";
-            if (!mFullscreen && adjustFocusToNextFocusableStackLocked(reason)) {
+            final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack()
+                    ? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
+            if (!mFullscreen && adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
                 // Try to move focus to the next visible stack with a running activity if this
                 // stack is not covering the entire screen.
                 return mStackSupervisor.resumeFocusedStackTopActivityLocked(
@@ -1993,8 +2052,6 @@
                     "resumeTopActivityLocked: No more activities go home");
             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             // Only resume home if on home display
-            final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
-                    HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
             return isOnHomeDisplay() &&
                     mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
         }
@@ -3004,16 +3061,18 @@
             } else {
                 final TaskRecord task = r.task;
                 if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
+                    final int taskToReturnTo = task.getTaskToReturnTo();
+
                     // For non-fullscreen stack, we want to move the focus to the next visible
                     // stack to prevent the home screen from moving to the top and obscuring
                     // other visible stacks.
-                    if (!mFullscreen && adjustFocusToNextFocusableStackLocked(myReason)) {
+                    if (!mFullscreen
+                            && adjustFocusToNextFocusableStackLocked(taskToReturnTo, myReason)) {
                         return;
                     }
                     // Move the home stack to the top if this stack is fullscreen or there is no
                     // other visible stack.
-                    if (mStackSupervisor.moveHomeStackTaskToTop(
-                            task.getTaskToReturnTo(), myReason)) {
+                    if (mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, myReason)) {
                         // Activity focus was already adjusted. Nothing else to do...
                         return;
                     }
@@ -3024,12 +3083,16 @@
         mService.setFocusedActivityLocked(mStackSupervisor.topRunningActivityLocked(), myReason);
     }
 
-    private boolean adjustFocusToNextFocusableStackLocked(String reason) {
+    private boolean adjustFocusToNextFocusableStackLocked(int taskToReturnTo, String reason) {
         final ActivityStack stack = getNextFocusableStackLocked();
         final String myReason = reason + " adjustFocusToNextFocusableStack";
         if (stack == null) {
             return false;
         }
+
+        if (stack.isHomeStack()) {
+            return mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, reason);
+        }
         return mService.setFocusedActivityLocked(stack.topRunningActivityLocked(), myReason);
     }
 
@@ -4843,7 +4906,9 @@
             // We only need to adjust focused stack if this stack is in focus.
             if (isOnHomeDisplay() && mStackSupervisor.isFocusedStack(this)) {
                 String myReason = reason + " leftTaskHistoryEmpty";
-                if (mFullscreen || !adjustFocusToNextFocusableStackLocked(myReason)) {
+                if (mFullscreen
+                        || !adjustFocusToNextFocusableStackLocked(
+                        task.getTaskToReturnTo(), myReason)) {
                     mStackSupervisor.moveHomeStackToFront(myReason);
                 }
             }
@@ -4867,18 +4932,18 @@
         // add the task to stack first, mTaskPositioner might need the stack association
         addTask(task, toTop, "createTaskRecord");
         final boolean isLockscreenShown = mService.mLockScreenShown == LOCK_SCREEN_SHOWN;
-        if (!layoutTaskInStack(task, info.layout) && mBounds != null && task.isResizeable()
+        if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable()
                 && !isLockscreenShown) {
             task.updateOverrideConfiguration(mBounds);
         }
         return task;
     }
 
-    boolean layoutTaskInStack(TaskRecord task, ActivityInfo.Layout layout) {
+    boolean layoutTaskInStack(TaskRecord task, ActivityInfo.WindowLayout windowLayout) {
         if (mTaskPositioner == null) {
             return false;
         }
-        mTaskPositioner.updateDefaultBounds(task, mTaskHistory, layout);
+        mTaskPositioner.updateDefaultBounds(task, mTaskHistory, windowLayout);
         return true;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7def1bd..950320e 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -52,6 +52,7 @@
 import android.hardware.input.InputManager;
 import android.hardware.input.InputManagerInternal;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
@@ -101,7 +102,9 @@
 import java.util.Objects;
 import java.util.Set;
 
+import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
@@ -120,7 +123,6 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -151,6 +153,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityManagerService.ANIMATE;
 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.am.ActivityManagerService.NOTIFY_FORCED_RESIZABLE_MSG;
 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
@@ -167,6 +170,7 @@
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
+import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
 
 public final class ActivityStackSupervisor implements DisplayListener {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
@@ -423,6 +427,11 @@
     boolean mAppVisibilitiesChangedSinceLastPause;
 
     /**
+     * Set of tasks that are in resizing mode during an app transition to fill the "void".
+     */
+    private final ArraySet<Integer> mResizingTasksDuringAnimation = new ArraySet<>();
+
+    /**
      * Description of a request to start a new activity, which has been held
      * due to app switches being disabled.
      */
@@ -1304,7 +1313,7 @@
     boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo,
             String resultWho, int requestCode, int callingPid, int callingUid,
             String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp,
-            ActivityRecord resultRecord, ActivityStack resultStack) {
+            ActivityRecord resultRecord, ActivityStack resultStack, ActivityOptions options) {
         final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
                 callingUid);
         if (startAnyPerm ==  PERMISSION_GRANTED) {
@@ -1358,6 +1367,19 @@
             Slog.w(TAG, message);
             return false;
         }
+        if (options != null && options.getLaunchTaskId() != -1) {
+            final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS,
+                    callingPid, callingUid);
+            if (startInTaskPerm != PERMISSION_GRANTED) {
+                final String msg = "Permission Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ") with launchTaskId="
+                        + options.getLaunchTaskId();
+                Slog.w(TAG, msg);
+                throw new SecurityException(msg);
+            }
+        }
+
         return true;
     }
 
@@ -1776,7 +1798,7 @@
                     // WM resizeTask must be done after the task is moved to the correct stack,
                     // because Task's setBounds() also updates dim layer's bounds, but that has
                     // dependency on the stack.
-                    mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig,
+                    mWindowManager.resizeTask(task.taskId, task.mBounds, task.mOverrideConfig,
                             false /* relayout */, false /* forced */);
                 }
             }
@@ -1788,6 +1810,8 @@
 
         if (DEBUG_STACK) Slog.d(TAG_STACK,
                 "findTaskToMoveToFront: moved to front of stack=" + task.stack);
+
+        showNonResizeableDockToastIfNeeded(task, INVALID_STACK_ID, task.stack.mStackId);
     }
 
     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
@@ -1924,10 +1948,39 @@
         }
     }
 
-    private void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
+    void deferUpdateBounds(int stackId) {
+        final ActivityStack stack = getStack(stackId);
+        if (stack != null) {
+            stack.deferUpdateBounds();
+        }
+    }
+
+    void continueUpdateBounds(int stackId) {
+        final ActivityStack stack = getStack(stackId);
+        if (stack != null) {
+            stack.continueUpdateBounds();
+        }
+    }
+
+    void notifyAppTransitionDone() {
+        continueUpdateBounds(HOME_STACK_ID);
+        for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
+            final int taskId = mResizingTasksDuringAnimation.valueAt(i);
+            if (anyTaskForIdLocked(taskId) != null) {
+                mWindowManager.setTaskDockedResizing(taskId, false);
+            }
+        }
+        mResizingTasksDuringAnimation.clear();
+    }
+
+    void resizeStackUncheckedLocked(ActivityStack stack, Rect bounds, Rect tempTaskBounds,
             Rect tempTaskInsetBounds) {
         bounds = TaskRecord.validateBounds(bounds);
 
+        if (!stack.updateBoundsAllowed(bounds, tempTaskBounds, tempTaskInsetBounds)) {
+            return;
+        }
+
         mTmpBounds.clear();
         mTmpConfigs.clear();
         mTmpInsetBounds.clear();
@@ -3309,10 +3362,14 @@
             return;
         }
 
-        if (!task.canGoInDockedStack() || task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) {
-            // Display warning toast if we tried to put a non-dockable task in the docked stack or
-            // the task was forced to be resizable by the system.
+        if (!task.canGoInDockedStack()) {
+            // Display a warning toast that we tried to put a non-dockable task in the docked stack.
             mWindowManager.scheduleShowNonResizeableDockToast(task.taskId);
+        } else if (task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) {
+            String packageName = task.getTopActivity() != null
+                    ? task.getTopActivity().appInfo.packageName : null;
+            mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0,
+                    packageName).sendToTarget();
         }
     }
 
@@ -4129,4 +4186,80 @@
         throw new IllegalStateException("Failed to find a stack behind stack=" + stack
                 + " in=" + stacks);
     }
+
+    /**
+     * Puts a task into resizing mode during the next app transition.
+     *
+     * @param taskId the id of the task to put into resizing mode
+     */
+    private void setResizingDuringAnimation(int taskId) {
+        mResizingTasksDuringAnimation.add(taskId);
+        mWindowManager.setTaskDockedResizing(taskId, true);
+    }
+
+    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
+        final TaskRecord task;
+        final int callingUid;
+        final String callingPackage;
+        final Intent intent;
+        final int userId;
+        final ActivityOptions activityOptions = (bOptions != null)
+                ? new ActivityOptions(bOptions) : null;
+        final int launchStackId = (activityOptions != null)
+                ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
+
+        if (launchStackId == HOME_STACK_ID) {
+            throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
+                    + taskId + " can't be launch in the home stack.");
+        }
+        task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
+        if (task == null) {
+            throw new IllegalArgumentException(
+                    "startActivityFromRecentsInner: Task " + taskId + " not found.");
+        }
+
+        if (launchStackId != INVALID_STACK_ID) {
+            if (launchStackId == DOCKED_STACK_ID) {
+                mWindowManager.setDockedStackCreateState(
+                        activityOptions.getDockCreateMode(), null /* initialBounds */);
+
+                // Defer updating the stack in which recents is until the app transition is done, to
+                // not run into issues where we still need to draw the task in recents but the
+                // docked stack is already created.
+                deferUpdateBounds(HOME_STACK_ID);
+                mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
+            }
+            if (task.stack.mStackId != launchStackId) {
+                moveTaskToStackLocked(
+                        taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
+                        ANIMATE);
+            }
+        }
+
+        // If the user must confirm credentials (e.g. when first launching a work app and the
+        // Work Challenge is present) let startActivityInPackage handle the intercepting.
+        if (!mService.mUserController.shouldConfirmCredentials(task.userId)
+                && task.getRootActivity() != null) {
+            mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
+
+            // If we are launching the task in the docked stack, put it into resizing mode so
+            // the window renders full-screen with the background filling the void. Also only
+            // call this at the end to make sure that tasks exists on the window manager side.
+            if (launchStackId == DOCKED_STACK_ID) {
+                setResizingDuringAnimation(taskId);
+            }
+            return ActivityManager.START_TASK_TO_FRONT;
+        }
+        callingUid = task.mCallingUid;
+        callingPackage = task.mCallingPackage;
+        intent = task.intent;
+        intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
+        userId = task.userId;
+            int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
+                    null, null, 0, 0, bOptions, userId, null, task);
+            if (launchStackId == DOCKED_STACK_ID) {
+                setResizingDuringAnimation(task.taskId);
+            }
+            return result;
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 13d90e3..76dfd01 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -26,6 +26,7 @@
 import static android.content.Intent.EXTRA_TASK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
 import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
 
 import android.app.KeyguardManager;
@@ -192,14 +193,14 @@
                 Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent },
                 new String[]{ resolvedType },
                 FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE, null);
-        final int flags = intent.getFlags();
         final KeyguardManager km = (KeyguardManager) mService.mContext
                 .getSystemService(KEYGUARD_SERVICE);
         final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId);
         if (newIntent == null) {
             return null;
         }
-        newIntent.setFlags(flags | FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        newIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
+                FLAG_ACTIVITY_TASK_ON_HOME);
         newIntent.putExtra(EXTRA_PACKAGE_NAME, aInfo.packageName);
         newIntent.putExtra(EXTRA_INTENT, new IntentSender(target));
         return newIntent;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index af69c93..e3ca3ea 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -362,7 +362,7 @@
 
         boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
-                resultRecord, resultStack);
+                resultRecord, resultStack, options);
         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                 callingPid, resolvedType, aInfo.applicationInfo);
 
@@ -547,12 +547,18 @@
         }
 
         if (startedActivityStackId == DOCKED_STACK_ID && prevFocusedStackId == HOME_STACK_ID) {
-            // We launch an activity while being in home stack, which means either launcher or
-            // recents into docked stack. We don't want the launched activity to be alone in a
-            // docked stack, so we want to immediately launch recents too.
-            if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
-            mWindowManager.showRecentApps();
-            return;
+            final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID);
+            final ActivityRecord topActivityHomeStack = homeStack != null
+                    ? homeStack.topRunningActivityLocked() : null;
+            if (topActivityHomeStack == null
+                    || topActivityHomeStack.mActivityType != RECENTS_ACTIVITY_TYPE) {
+                // We launch an activity while being in home stack, which means either launcher or
+                // recents into docked stack. We don't want the launched activity to be alone in a
+                // docked stack, so we want to immediately launch recents too.
+                if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
+                mWindowManager.showRecentApps();
+                return;
+            }
         }
 
         if (startedActivityStackId == PINNED_STACK_ID
@@ -879,6 +885,9 @@
 
         ActivityRecord intentActivity = getReusableIntentActivity();
 
+        final int preferredLaunchStackId =
+                (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
+
         if (intentActivity != null) {
             // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
             // still needs to be a lock task mode violation since the task gets cleared out and
@@ -938,6 +947,8 @@
                 // We didn't do anything...  but it was needed (a.k.a., client don't use that
                 // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
                 resumeTargetStackIfNeeded();
+                mSupervisor.showNonResizeableDockToastIfNeeded(mStartActivity.task,
+                        preferredLaunchStackId, mTargetStack.mStackId);
                 return START_TASK_TO_FRONT;
             }
         }
@@ -977,6 +988,8 @@
             }
             top.deliverNewIntentLocked(
                     mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
+            mSupervisor.showNonResizeableDockToastIfNeeded(mStartActivity.task,
+                    preferredLaunchStackId, mTargetStack.mStackId);
             return START_DELIVERED_TO_TOP;
         }
 
@@ -1063,8 +1076,6 @@
         }
         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
 
-        final int preferredLaunchStackId =
-                (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
         mSupervisor.showNonResizeableDockToastIfNeeded(
                 mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId);
 
@@ -1297,7 +1308,10 @@
         // same component, then instead of launching bring that one to the front.
         putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
         ActivityRecord intentActivity = null;
-        if (putIntoExistingTask) {
+        if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
+            final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
+            intentActivity = task != null ? task.getTopActivity() : null;
+        } else if (putIntoExistingTask) {
             // See if there is a task to bring to the front.  If this is a SINGLE_INSTANCE
             // activity, there can be one and only one instance of it in the history, and it is
             // always in its own unique task, so we do a special search.
@@ -1349,6 +1363,15 @@
                                 intentActivity.task, mNoAnimation, mOptions,
                                 mStartActivity.appTimeTracker, "bringingFoundTaskToFront");
                         mMovedToFront = true;
+                    } else if ((launchStack.mStackId == DOCKED_STACK_ID
+                            || launchStack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID)
+                            && (mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
+                        // If we want to launch adjacent and mTargetStack is not the computed
+                        // launch stack - move task to top of computed stack.
+                        mSupervisor.moveTaskToStackLocked(intentActivity.task.taskId,
+                                launchStack.mStackId, ON_TOP, FORCE_FOCUS, "launchToSide",
+                                ANIMATE);
+                        mMovedToFront = true;
                     }
                     mOptions = null;
                 }
@@ -1756,26 +1779,41 @@
         if (!launchToSideAllowed || (launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) {
             return null;
         }
+        // Otherwise handle adjacent launch.
 
         // The parent activity doesn't want to launch the activity on top of itself, but
         // instead tries to put it onto other side in side-by-side mode.
         final ActivityStack parentStack = task != null ? task.stack
                 : r.mInitialActivityContainer != null ? r.mInitialActivityContainer.mStack
                 : mSupervisor.mFocusedStack;
-        if (parentStack != null && parentStack.mStackId == DOCKED_STACK_ID) {
-            // If parent was in docked stack, the natural place to launch another activity
-            // will be fullscreen, so it can appear alongside the docked window.
-            return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
+
+        if (parentStack != mSupervisor.mFocusedStack) {
+            // If task's parent stack is not focused - use it during adjacent launch.
+            return parentStack;
         } else {
-            // If the parent is not in the docked stack, we check if there is docked window
-            // and if yes, we will launch into that stack. If not, we just put the new
-            // activity into parent's stack, because we can't find a better place.
-            final ActivityStack stack = mSupervisor.getStack(DOCKED_STACK_ID);
-            if (stack != null && stack.getStackVisibilityLocked(r) == STACK_INVISIBLE) {
-                // There is a docked stack, but it isn't visible, so we can't launch into that.
-                return null;
+            if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
+                // If task is already on top of focused stack - use it. We don't want to move the
+                // existing focused task to adjacent stack, just deliver new intent in this case.
+                return mSupervisor.mFocusedStack;
+            }
+
+            if (parentStack != null && parentStack.mStackId == DOCKED_STACK_ID) {
+                // If parent was in docked stack, the natural place to launch another activity
+                // will be fullscreen, so it can appear alongside the docked window.
+                return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED,
+                        ON_TOP);
             } else {
-                return stack;
+                // If the parent is not in the docked stack, we check if there is docked window
+                // and if yes, we will launch into that stack. If not, we just put the new
+                // activity into parent's stack, because we can't find a better place.
+                final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
+                if (dockedStack != null
+                        && dockedStack.getStackVisibilityLocked(r) == STACK_INVISIBLE) {
+                    // There is a docked stack, but it isn't visible, so we can't launch into that.
+                    return null;
+                } else {
+                    return dockedStack;
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 71a1f97..ffa3b5b 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1170,7 +1170,8 @@
         }
 
         if (useCheckinFormat) {
-            List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
+            List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
+                    PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_ALL);
             if (isRealCheckin) {
                 // For a real checkin, first we want to prefer to use the last complete checkin
                 // file if there is one.
diff --git a/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java b/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java
index 39c6ce6..9fb51c1 100644
--- a/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java
+++ b/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java
@@ -122,7 +122,8 @@
             // Battery Stats stores the GPS sensors with a bogus key in this API. Pull it out
             // as a separate metric here so as to not expose that in the API.
             if (sensorId == BatteryStats.Uid.Sensor.GPS) {
-                addTimer(uidWriter, UidHealthStats.TIMER_GPS_SENSOR, sensors.valueAt(i).getSensorTime());
+                addTimer(uidWriter, UidHealthStats.TIMER_GPS_SENSOR,
+                        sensors.valueAt(i).getSensorTime());
             } else {
                 addTimers(uidWriter, UidHealthStats.TIMERS_SENSORS, Integer.toString(sensorId),
                         sensors.valueAt(i).getSensorTime());
@@ -131,7 +132,7 @@
 
         // STATS_PIDS
         pids = uid.getPidStats();
-        N = sensors.size();
+        N = pids.size();
         for (int i=0; i<N; i++) {
             final HealthStatsWriter writer = new HealthStatsWriter(PidHealthStats.CONSTANTS);
             writePid(writer, pids.valueAt(i));
@@ -241,7 +242,8 @@
         addTimer(uidWriter, UidHealthStats.TIMER_CAMERA, uid.getCameraTurnedOnTimer());
 
         // TIMER_FOREGROUND_ACTIVITY
-        addTimer(uidWriter, UidHealthStats.TIMER_FOREGROUND_ACTIVITY, uid.getForegroundActivityTimer());
+        addTimer(uidWriter, UidHealthStats.TIMER_FOREGROUND_ACTIVITY,
+                uid.getForegroundActivityTimer());
 
         // TIMER_BLUETOOTH_SCAN
         addTimer(uidWriter, UidHealthStats.TIMER_BLUETOOTH_SCAN, uid.getBluetoothScanTimer());
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
index 4ba1d0d..d652341 100644
--- a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -109,22 +109,22 @@
      *
      * @param task Task for which we want to find bounds that won't collide with other.
      * @param tasks Existing tasks with which we don't want to collide.
-     * @param layout Optional information from the client about how it would like to be sized
+     * @param windowLayout Optional information from the client about how it would like to be sized
      *                      and positioned.
      */
     void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks,
-            @Nullable ActivityInfo.Layout layout) {
+            @Nullable ActivityInfo.WindowLayout windowLayout) {
         if (!mDefaultStartBoundsConfigurationSet) {
             return;
         }
-        if (layout == null) {
+        if (windowLayout == null) {
             positionCenter(task, tasks, mDefaultFreeformWidth, mDefaultFreeformHeight);
             return;
         }
-        int width = getFinalWidth(layout);
-        int height = getFinalHeight(layout);
-        int verticalGravity = layout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
-        int horizontalGravity = layout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+        int width = getFinalWidth(windowLayout);
+        int height = getFinalHeight(windowLayout);
+        int verticalGravity = windowLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
+        int horizontalGravity = windowLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
         if (verticalGravity == Gravity.TOP) {
             if (horizontalGravity == Gravity.RIGHT) {
                 positionTopRight(task, tasks, width, height);
@@ -140,30 +140,30 @@
         } else {
             // Some fancy gravity setting that we don't support yet. We just put the activity in the
             // center.
-            Slog.w(TAG, "Received unsupported gravity: " + layout.gravity
+            Slog.w(TAG, "Received unsupported gravity: " + windowLayout.gravity
                     + ", positioning in the center instead.");
             positionCenter(task, tasks, width, height);
         }
     }
 
-    private int getFinalWidth(ActivityInfo.Layout layout) {
+    private int getFinalWidth(ActivityInfo.WindowLayout windowLayout) {
         int width = mDefaultFreeformWidth;
-        if (layout.width > 0) {
-            width = layout.width;
+        if (windowLayout.width > 0) {
+            width = windowLayout.width;
         }
-        if (layout.widthFraction > 0) {
-            width = (int) (mAvailableRect.width() * layout.widthFraction);
+        if (windowLayout.widthFraction > 0) {
+            width = (int) (mAvailableRect.width() * windowLayout.widthFraction);
         }
         return width;
     }
 
-    private int getFinalHeight(ActivityInfo.Layout layout) {
+    private int getFinalHeight(ActivityInfo.WindowLayout windowLayout) {
         int height = mDefaultFreeformHeight;
-        if (layout.height > 0) {
-            height = layout.height;
+        if (windowLayout.height > 0) {
+            height = windowLayout.height;
         }
-        if (layout.heightFraction > 0) {
-            height = (int) (mAvailableRect.height() * layout.heightFraction);
+        if (windowLayout.heightFraction > 0) {
+            height = (int) (mAvailableRect.height() * windowLayout.heightFraction);
         }
         return height;
     }
diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java
new file mode 100644
index 0000000..1825c88
--- /dev/null
+++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
+import android.app.AppOpsManager;
+import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.util.ProgressReporter;
+
+import java.util.List;
+
+/**
+ * Simple broadcaster that sends {@link Intent#ACTION_PRE_BOOT_COMPLETED} to all
+ * system apps that register for it. Override {@link #onFinished()} to handle
+ * when all broadcasts are finished.
+ */
+public abstract class PreBootBroadcaster extends IIntentReceiver.Stub {
+    private static final String TAG = "PreBootBroadcaster";
+
+    private final ActivityManagerService mService;
+    private final int mUserId;
+    private final ProgressReporter mProgress;
+
+    private final Intent mIntent;
+    private final List<ResolveInfo> mTargets;
+
+    private int mIndex = 0;
+
+    public PreBootBroadcaster(ActivityManagerService service, int userId,
+            ProgressReporter progress) {
+        mService = service;
+        mUserId = userId;
+        mProgress = progress;
+
+        mIntent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
+        mIntent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
+
+        mTargets = mService.mContext.getPackageManager().queryBroadcastReceiversAsUser(mIntent,
+                MATCH_SYSTEM_ONLY, UserHandle.of(userId));
+    }
+
+    public void sendNext() {
+        if (mIndex >= mTargets.size()) {
+            onFinished();
+            return;
+        }
+
+        final ResolveInfo ri = mTargets.get(mIndex++);
+        final ComponentName componentName = ri.activityInfo.getComponentName();
+
+        final CharSequence label = ri.activityInfo.loadLabel(mService.mContext.getPackageManager());
+        mProgress.setProgress(mIndex, mTargets.size(),
+                mService.mContext.getString(R.string.android_preparing_apk, label));
+
+        Slog.i(TAG, "Pre-boot of " + componentName.toShortString() + " for user " + mUserId);
+        EventLogTags.writeAmPreBoot(mUserId, componentName.getPackageName());
+
+        mIntent.setComponent(componentName);
+        mService.broadcastIntentLocked(null, null, mIntent, null, this, 0, null, null, null,
+                AppOpsManager.OP_NONE, null, true, false, ActivityManagerService.MY_PID,
+                Process.SYSTEM_UID, mUserId);
+    }
+
+    @Override
+    public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
+            boolean ordered, boolean sticky, int sendingUser) {
+        sendNext();
+    }
+
+    public abstract void onFinished();
+}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b4aa4cf..bacbd3e 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -116,6 +116,7 @@
     boolean killed;             // True once we know the process has been killed
     boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
     boolean reportedInteraction;// Whether we have told usage stats about it being an interaction
+    boolean unlocked;           // True when proc was started in user unlocked state
     long interactionEventTime;  // The time we sent the last interaction event
     long fgInteractionTime;     // When we became foreground for interaction purposes
     String waitingToKill;       // Process is waiting to be killed when in the bg, and reason
@@ -558,7 +559,7 @@
             }
             EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
             Process.killProcessQuiet(pid);
-            Process.killProcessGroup(info.uid, pid);
+            Process.killProcessGroup(uid, pid);
             if (!persistent) {
                 killed = true;
                 killedByAm = true;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 4eae45c..27acd91 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -72,8 +72,6 @@
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
@@ -254,9 +252,10 @@
     // The information is persisted and used to determine the appropriate stack to launch the
     // task into on restore.
     Rect mLastNonFullscreenBounds = null;
-    // Minimal size for width/height of this task when it's resizeable. -1 means it should use the
-    // default minimal size.
-    final int mMinimalSize;
+    // Minimal width and height of this task when it's resizeable. -1 means it should use the
+    // default minimal width/height.
+    int mMinimalWidth;
+    int mMinimalHeight;
 
     // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible)
     // This number will be assigned when we evaluate OOM scores for all visible tasks.
@@ -281,7 +280,7 @@
         mCallingUid = info.applicationInfo.uid;
         mCallingPackage = info.packageName;
         setIntent(_intent, info);
-        mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
+        setMinDimensions(info);
     }
 
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
@@ -301,6 +300,7 @@
         mCallingUid = info.applicationInfo.uid;
         mCallingPackage = info.packageName;
         setIntent(_intent, info);
+        setMinDimensions(info);
 
         taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
         isPersistable = true;
@@ -311,7 +311,6 @@
         taskType = APPLICATION_ACTIVITY_TYPE;
         mTaskToReturnTo = HOME_ACTIVITY_TYPE;
         lastTaskDescription = _taskDescription;
-        mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
     }
 
     private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
@@ -365,7 +364,7 @@
         mResizeMode = resizeMode;
         mPrivileged = privileged;
         ActivityInfo info = (mActivities.size() > 0) ? mActivities.get(0).info : null;
-        mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1;
+        setMinDimensions(info);
     }
 
     void touchActiveTime() {
@@ -471,6 +470,17 @@
         setLockTaskAuth();
     }
 
+    /** Sets the original minimal width and height. */
+    private void setMinDimensions(ActivityInfo info) {
+        if (info != null && info.windowLayout != null) {
+            mMinimalWidth = info.windowLayout.minimalWidth;
+            mMinimalHeight = info.windowLayout.minimalHeight;
+        } else {
+            mMinimalWidth = -1;
+            mMinimalHeight = -1;
+        }
+    }
+
     /**
      * Return true if the input activity has the same intent resolution as the intent this task
      * record is based on (normally the root activity intent).
@@ -1342,35 +1352,41 @@
         if (bounds == null) {
             return;
         }
-        int minimalSize = mMinimalSize;
+        int minimalWidth = mMinimalWidth;
+        int minimalHeight = mMinimalHeight;
         // If the task has no requested minimal size, we'd like to enforce a minimal size
         // so that the user can not render the task too small to manipulate. We don't need
         // to do this for the pinned stack as the bounds are controlled by the system.
-        if (minimalSize == -1 && stack.mStackId != PINNED_STACK_ID) {
-            minimalSize = mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask;
+        if (stack.mStackId != PINNED_STACK_ID) {
+            if (minimalWidth == -1) {
+                minimalWidth = mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask;
+            }
+            if (minimalHeight == -1) {
+                minimalHeight = mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask;
+            }
         }
-        final boolean adjustWidth = minimalSize > bounds.width();
-        final boolean adjustHeight = minimalSize > bounds.height();
+        final boolean adjustWidth = minimalWidth > bounds.width();
+        final boolean adjustHeight = minimalHeight > bounds.height();
         if (!(adjustWidth || adjustHeight)) {
             return;
         }
 
         if (adjustWidth) {
             if (mBounds != null && bounds.right == mBounds.right) {
-                bounds.left = bounds.right - minimalSize;
+                bounds.left = bounds.right - minimalWidth;
             } else {
                 // Either left bounds match, or neither match, or the previous bounds were
                 // fullscreen and we default to keeping left.
-                bounds.right = bounds.left + minimalSize;
+                bounds.right = bounds.left + minimalWidth;
             }
         }
         if (adjustHeight) {
             if (mBounds != null && bounds.bottom == mBounds.bottom) {
-                bounds.top = bounds.bottom - minimalSize;
+                bounds.top = bounds.bottom - minimalHeight;
             } else {
                 // Either top bounds match, or neither match, or the previous bounds were
                 // fullscreen and we default to keeping top.
-                bounds.bottom = bounds.top + minimalSize;
+                bounds.bottom = bounds.top + minimalHeight;
             }
         }
     }
@@ -1502,6 +1518,9 @@
     Rect updateOverrideConfigurationFromLaunchBounds() {
         final Rect bounds = validateBounds(getLaunchBounds());
         updateOverrideConfiguration(bounds);
+        if (bounds != null) {
+            bounds.set(mBounds);
+        }
         return bounds;
     }
 
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 5baba52..c59591e9 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -24,6 +24,7 @@
 import static android.app.ActivityManager.USER_OP_SUCCESS;
 import static android.content.Context.KEYGUARD_SERVICE;
 import static android.os.Process.SYSTEM_UID;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -37,6 +38,10 @@
 import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
 import static com.android.server.am.ActivityManagerService.SYSTEM_USER_UNLOCK_MSG;
 import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
+import static com.android.server.am.UserState.STATE_BOOTING;
+import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
+import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
+import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
@@ -53,6 +58,7 @@
 import android.content.pm.UserInfo;
 import android.os.BatteryStats;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
@@ -77,6 +83,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.ProgressReporter;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
 import com.android.server.pm.UserManagerService;
@@ -86,6 +93,7 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -219,9 +227,7 @@
             // consistent developer events. We step into RUNNING_LOCKED here,
             // but we might immediately step into RUNNING below if the user
             // storage is already unlocked.
-            if (uss.state == UserState.STATE_BOOTING) {
-                uss.setState(UserState.STATE_RUNNING_LOCKED);
-
+            if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
                 Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
@@ -236,11 +242,10 @@
     }
 
     /**
-     * Consider stepping from {@link UserState#STATE_RUNNING_LOCKED} into
-     * {@link UserState#STATE_RUNNING}, which only occurs if the user storage is
-     * actually unlocked.
+     * Step from {@link UserState#STATE_RUNNING_LOCKED} to
+     * {@link UserState#STATE_RUNNING_UNLOCKING}.
      */
-    void finishUserUnlock(UserState uss) {
+    void finishUserUnlocking(final UserState uss, final ProgressReporter progress) {
         final int userId = uss.mHandle.getIdentifier();
         synchronized (mService) {
             // Bail if we ended up with a stale user
@@ -249,14 +254,58 @@
             // Only keep marching forward if user is actually unlocked
             if (!isUserKeyUnlocked(userId)) return;
 
-            if (uss.state == UserState.STATE_RUNNING_LOCKED) {
-                uss.setState(UserState.STATE_RUNNING);
-
-                // Give user manager a chance to prepare app storage
+            if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
+                // Prepare app storage before we go any further
+                progress.setProgress(5, mService.mContext.getString(R.string.android_start_title));
                 mUserManager.onBeforeUnlockUser(userId);
+                progress.setProgress(20);
 
+                // Send PRE_BOOT broadcasts if fingerprint changed
+                final UserInfo info = getUserInfo(userId);
+                if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
+                    progress.startSegment(80);
+                    new PreBootBroadcaster(mService, userId, progress) {
+                        @Override
+                        public void onFinished() {
+                            finishUserUnlocked(uss, progress);
+                        }
+                    }.sendNext();
+                } else {
+                    finishUserUnlocked(uss, progress);
+                }
+            }
+        }
+    }
+
+    /**
+     * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
+     * {@link UserState#STATE_RUNNING_UNLOCKED}.
+     */
+    void finishUserUnlocked(UserState uss, ProgressReporter progress) {
+        try {
+            finishUserUnlockedInternal(uss);
+        } finally {
+            progress.finish();
+        }
+    }
+
+    void finishUserUnlockedInternal(UserState uss) {
+        final int userId = uss.mHandle.getIdentifier();
+        synchronized (mService) {
+            // Bail if we ended up with a stale user
+            if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
+
+            // Only keep marching forward if user is actually unlocked
+            if (!isUserKeyUnlocked(userId)) return;
+
+            if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
+                // Remember that we logged in
+                mUserManager.onUserLoggedIn(userId);
+
+                // Dispatch unlocked to system services
                 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
 
+                // Dispatch unlocked to external apps
                 final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
                 unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                 unlockedIntent.addFlags(
@@ -769,7 +818,7 @@
         return result;
     }
 
-    boolean unlockUser(final int userId, byte[] token, byte[] secret) {
+    boolean unlockUser(final int userId, byte[] token, byte[] secret, ProgressReporter progress) {
         if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
                 != PackageManager.PERMISSION_GRANTED) {
             String msg = "Permission Denial: unlockUser() from pid="
@@ -782,7 +831,7 @@
 
         final long binderToken = Binder.clearCallingIdentity();
         try {
-            return unlockUserCleared(userId, token, secret);
+            return unlockUserCleared(userId, token, secret, progress);
         } finally {
             Binder.restoreCallingIdentity(binderToken);
         }
@@ -796,14 +845,20 @@
      */
     boolean maybeUnlockUser(final int userId) {
         // Try unlocking storage using empty token
-        return unlockUserCleared(userId, null, null);
+        return unlockUserCleared(userId, null, null, ProgressReporter.NO_OP);
     }
 
-    boolean unlockUserCleared(final int userId, byte[] token, byte[] secret) {
+    boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
+            ProgressReporter progress) {
         synchronized (mService) {
             // Bail if already running unlocked
             final UserState uss = mStartedUsers.get(userId);
-            if (uss.state == UserState.STATE_RUNNING) return true;
+            switch (uss.state) {
+                case STATE_RUNNING_UNLOCKING:
+                case STATE_RUNNING_UNLOCKED:
+                    progress.finish();
+                    return true;
+            }
         }
 
         if (!isUserKeyUnlocked(userId)) {
@@ -813,13 +868,14 @@
                 mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
             } catch (RemoteException | RuntimeException e) {
                 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
+                progress.finish();
                 return false;
             }
         }
 
         synchronized (mService) {
             final UserState uss = mStartedUsers.get(userId);
-            finishUserUnlock(uss);
+            finishUserUnlocking(uss, progress);
         }
 
         return true;
@@ -971,7 +1027,6 @@
             mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
         }
         EventLogTags.writeAmSwitchUser(newUserId);
-        getUserManager().onUserForeground(newUserId);
         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
     }
 
@@ -1219,7 +1274,8 @@
                 unlocked = false;
                 break;
 
-            case UserState.STATE_RUNNING:
+            case UserState.STATE_RUNNING_UNLOCKING:
+            case UserState.STATE_RUNNING_UNLOCKED:
                 unlocked = true;
                 break;
         }
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index 7b18a17..6e2342b 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -33,14 +33,16 @@
 
     // User is first coming up.
     public final static int STATE_BOOTING = 0;
-    // User is in the locked running state.
+    // User is in the locked state.
     public final static int STATE_RUNNING_LOCKED = 1;
-    // User is in the normal running state.
-    public final static int STATE_RUNNING = 2;
+    // User is in the unlocking state.
+    public final static int STATE_RUNNING_UNLOCKING = 2;
+    // User is in the running state.
+    public final static int STATE_RUNNING_UNLOCKED = 3;
     // User is in the initial process of being stopped.
-    public final static int STATE_STOPPING = 3;
+    public final static int STATE_STOPPING = 4;
     // User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN.
-    public final static int STATE_SHUTDOWN = 4;
+    public final static int STATE_SHUTDOWN = 5;
 
     public final UserHandle mHandle;
     public final ArrayList<IStopUserCallback> mStopCallbacks
@@ -61,6 +63,17 @@
         mHandle = handle;
     }
 
+    public boolean setState(int oldState, int newState) {
+        if (state == oldState) {
+            setState(newState);
+            return true;
+        } else {
+            Slog.w(TAG, "Expected user " + mHandle.getIdentifier() + " in state "
+                    + stateToString(oldState) + " but was in state " + stateToString(state));
+            return false;
+        }
+    }
+
     public void setState(int newState) {
         if (DEBUG_MU) {
             Slog.i(TAG, "User " + mHandle.getIdentifier() + " state changed from "
@@ -74,7 +87,8 @@
         switch (state) {
             case STATE_BOOTING: return "BOOTING";
             case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED";
-            case STATE_RUNNING: return "RUNNING";
+            case STATE_RUNNING_UNLOCKING: return "RUNNING_UNLOCKING";
+            case STATE_RUNNING_UNLOCKED: return "RUNNING_UNLOCKED";
             case STATE_STOPPING: return "STOPPING";
             case STATE_SHUTDOWN: return "SHUTDOWN";
             default: return Integer.toString(state);
@@ -84,7 +98,6 @@
     void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
         pw.print("state="); pw.print(stateToString(state));
-        pw.print(" lastState="); pw.print(stateToString(lastState));
         if (switching) pw.print(" SWITCHING");
         if (initializing) pw.print(" INITIALIZING");
         pw.println();
diff --git a/services/core/java/com/android/server/connectivity/MetricsLoggerService.java b/services/core/java/com/android/server/connectivity/MetricsLoggerService.java
index f6dc9b9..7cac227 100644
--- a/services/core/java/com/android/server/connectivity/MetricsLoggerService.java
+++ b/services/core/java/com/android/server/connectivity/MetricsLoggerService.java
@@ -60,7 +60,7 @@
     private long mLastSentEventTimeMillis = System.currentTimeMillis();
 
     private final void enforceConnectivityInternalPermission() {
-        getContext().enforceCallingPermission(
+        getContext().enforceCallingOrSelfPermission(
                 android.Manifest.permission.CONNECTIVITY_INTERNAL,
                 "MetricsLoggerService");
     }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index b4c71c1..c5d38cb 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -32,7 +32,6 @@
 import com.android.internal.util.AsyncChannel;
 import com.android.server.ConnectivityService;
 import com.android.server.connectivity.NetworkMonitor;
-import com.android.server.connectivity.ApfFilter;
 
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -164,8 +163,6 @@
     // Used by ConnectivityService to keep track of 464xlat.
     public Nat464Xlat clatd;
 
-    public ApfFilter apfFilter;
-
     public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
             LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
             NetworkMisc misc, NetworkRequest defaultRequest, ConnectivityService connService) {
@@ -178,7 +175,6 @@
         currentScore = score;
         networkMonitor = connService.createNetworkMonitor(context, handler, this, defaultRequest);
         networkMisc = misc;
-        apfFilter.maybeInstall(connService, this);
     }
 
     /**
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index bce7733..bbb162e 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -34,6 +34,8 @@
 import android.net.ProxyInfo;
 import android.net.TrafficStats;
 import android.net.Uri;
+import android.net.metrics.CaptivePortalCheckResultEvent;
+import android.net.metrics.CaptivePortalStateChangeEvent;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
@@ -297,9 +299,13 @@
                     transitionTo(mLingeringState);
                     return HANDLED;
                 case CMD_NETWORK_CONNECTED:
+                    CaptivePortalStateChangeEvent.logEvent(
+                            CaptivePortalStateChangeEvent.NETWORK_MONITOR_CONNECTED);
                     transitionTo(mEvaluatingState);
                     return HANDLED;
                 case CMD_NETWORK_DISCONNECTED:
+                    CaptivePortalStateChangeEvent.logEvent(
+                            CaptivePortalStateChangeEvent.NETWORK_MONITOR_DISCONNECTED);
                     if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
                         mContext.unregisterReceiver(mLaunchCaptivePortalAppBroadcastReceiver);
                         mLaunchCaptivePortalAppBroadcastReceiver = null;
@@ -349,6 +355,8 @@
     private class ValidatedState extends State {
         @Override
         public void enter() {
+            CaptivePortalStateChangeEvent.logEvent(
+                   CaptivePortalStateChangeEvent.NETWORK_MONITOR_VALIDATED);
             mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
                     NETWORK_TEST_RESULT_VALID, 0, mNetworkAgentInfo));
         }
@@ -457,6 +465,8 @@
                     // will be unresponsive. isCaptivePortal() could be executed on another Thread
                     // if this is found to cause problems.
                     int httpResponseCode = isCaptivePortal();
+                    CaptivePortalCheckResultEvent.logEvent(mNetworkAgentInfo.network.netId,
+                            httpResponseCode);
                     if (httpResponseCode == 204) {
                         transitionTo(mValidatedState);
                     } else if (httpResponseCode >= 200 && httpResponseCode <= 399) {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 4527f1f..715d2d8 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -17,12 +17,12 @@
 package com.android.server.display;
 
 import android.content.res.Resources;
-import android.os.Build;
 import com.android.server.LocalServices;
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -31,7 +31,6 @@
 import android.os.Trace;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.SparseBooleanArray;
 import android.view.Display;
 import android.view.DisplayEventReceiver;
 import android.view.Surface;
@@ -388,7 +387,7 @@
                     mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
                             | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
                     if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)
-                            || (Build.HARDWARE.contains("goldfish")
+                            || (Build.IS_EMULATOR
                             && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
                         mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
                     }
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 5b1cedc..fc412e3 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -20,6 +20,7 @@
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE;
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
+import static android.provider.Settings.ACTION_VPN_SETTINGS;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -66,9 +67,6 @@
 
     private static final String ACTION_LOCKDOWN_RESET = "com.android.server.action.LOCKDOWN_RESET";
 
-    private static final String ACTION_VPN_SETTINGS = "android.net.vpn.SETTINGS";
-    private static final String EXTRA_PICK_LOCKDOWN = "android.net.vpn.PICK_LOCKDOWN";
-
     private static final int ROOT_UID = 0;
 
     private final Context mContext;
@@ -101,7 +99,6 @@
         mProfile = Preconditions.checkNotNull(profile);
 
         final Intent configIntent = new Intent(ACTION_VPN_SETTINGS);
-        configIntent.putExtra(EXTRA_PICK_LOCKDOWN, true);
         mConfigIntent = PendingIntent.getActivity(mContext, 0, configIntent, 0);
 
         final Intent resetIntent = new Intent(ACTION_LOCKDOWN_RESET);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 49ae293..c75e287 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -687,7 +687,7 @@
                 // global background data policy
                 if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
                 synchronized (mRulesLock) {
-                    updateRestrictDataRulesForUidLocked(uid);
+                    updateRestrictionRulesForUidLocked(uid);
                 }
             }
         }
@@ -705,7 +705,7 @@
             if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
             synchronized (mRulesLock) {
                 mUidPolicy.delete(uid);
-                updateRestrictDataRulesForUidLocked(uid);
+                updateRuleForRestrictBackgroundLocked(uid);
                 writePolicyLocked();
             }
         }
@@ -1678,7 +1678,7 @@
         mUidPolicy.put(uid, policy);
 
         // uid policy changed, recompute rules and persist policy.
-        updateRestrictDataRulesForUidLocked(uid);
+        updateRuleForRestrictBackgroundLocked(uid);
         if (persist) {
             writePolicyLocked();
         }
@@ -1897,7 +1897,7 @@
             maybeRefreshTrustedTime();
             synchronized (mRulesLock) {
                 mRestrictBackground = restrictBackground;
-                updateRulesForRestrictDataLocked();
+                updateRulesForRestrictBackgroundLocked();
                 updateNotificationsLocked();
                 writePolicyLocked();
             }
@@ -2272,7 +2272,7 @@
 
                 final int rule = mUidRules.get(uid, RULE_UNKNOWN);
                 fout.print(" rule=");
-                fout.print(DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule));
+                fout.print(ruleToString(rule));
 
                 fout.println();
             }
@@ -2280,6 +2280,10 @@
         }
     }
 
+    private String ruleToString(int rule) {
+        return DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule);
+    }
+
     @Override
     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
             String[] args, ResultReceiver resultReceiver) throws RemoteException {
@@ -2296,57 +2300,73 @@
         }
     }
 
-    boolean isUidForegroundLocked(int uid) {
+    private boolean isUidForegroundLocked(int uid) {
+        return isUidStateForegroundLocked(
+                mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY));
+    }
+
+    private boolean isUidStateForegroundLocked(int state) {
         // only really in foreground when screen is also on
-        return mScreenOn && mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY)
-                <= ActivityManager.PROCESS_STATE_TOP;
+        return mScreenOn && state <= ActivityManager.PROCESS_STATE_TOP;
     }
 
     /**
      * Process state of UID changed; if needed, will trigger
      * {@link #updateRestrictDataRulesForUidLocked(int)}.
      */
-    void updateUidStateLocked(int uid, int uidState) {
+    private void updateUidStateLocked(int uid, int uidState) {
         final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
         if (oldUidState != uidState) {
             // state changed, push updated rules
             mUidState.put(uid, uidState);
-            updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
+            updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState, uidState);
             if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState)
                     != isProcStateAllowedWhileIdleOrPowerSaveMode(uidState) ) {
                 if (mDeviceIdleMode) {
                     updateRuleForDeviceIdleLocked(uid);
                 }
                 if (mRestrictPower) {
-                    updateRulesForRestrictPowerLocked(uid);
+                    updateRuleForRestrictPowerLocked(uid);
                 }
             }
+            updateNetworkStats(uid, isUidStateForegroundLocked(uidState));
         }
     }
 
-    void removeUidStateLocked(int uid) {
+    private void removeUidStateLocked(int uid) {
         final int index = mUidState.indexOfKey(uid);
         if (index >= 0) {
             final int oldUidState = mUidState.valueAt(index);
             mUidState.removeAt(index);
             if (oldUidState != ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
-                updateRulesForUidStateChangeLocked(uid, oldUidState,
+                updateRestrictBackgroundRulesOnUidStatusChangedLocked(uid, oldUidState,
                         ActivityManager.PROCESS_STATE_CACHED_EMPTY);
                 if (mDeviceIdleMode) {
                     updateRuleForDeviceIdleLocked(uid);
                 }
                 if (mRestrictPower) {
-                    updateRulesForRestrictPowerLocked(uid);
+                    updateRuleForRestrictPowerLocked(uid);
                 }
+                updateNetworkStats(uid, false);
             }
         }
     }
 
-    void updateRulesForUidStateChangeLocked(int uid, int oldUidState, int newUidState) {
+    // adjust stats accounting based on foreground status
+    private void updateNetworkStats(int uid, boolean uidForeground) {
+        try {
+            mNetworkStats.setUidForeground(uid, uidForeground);
+        } catch (RemoteException e) {
+            // ignored; service lives in system_server
+        }
+    }
+
+    private void updateRestrictBackgroundRulesOnUidStatusChangedLocked(int uid, int oldUidState,
+            int newUidState) {
         final boolean oldForeground = oldUidState <= ActivityManager.PROCESS_STATE_TOP;
         final boolean newForeground = newUidState <= ActivityManager.PROCESS_STATE_TOP;
         if (oldForeground != newForeground) {
-            updateRestrictDataRulesForUidLocked(uid);
+            updateRuleForRestrictBackgroundLocked(uid);
         }
     }
 
@@ -2370,7 +2390,7 @@
         for (int i = 0; i < size; i++) {
             if (mUidState.valueAt(i) <= ActivityManager.PROCESS_STATE_TOP) {
                 final int uid = mUidState.keyAt(i);
-                updateRestrictDataRulesForUidLocked(uid);
+                updateRestrictionRulesForUidLocked(uid);
             }
         }
     }
@@ -2384,7 +2404,7 @@
                 mUidFirewallPowerSaveRules);
     }
 
-    void updateRulesForRestrictPowerLocked(int uid) {
+    void updateRuleForRestrictPowerLocked(int uid) {
         updateRulesForWhitelistedPowerSaveLocked(uid, mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
     }
 
@@ -2397,8 +2417,8 @@
         updateRulesForWhitelistedPowerSaveLocked(uid, mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
     }
 
-    // NOTE: since both fw_dozable and fw_powersave uses the same map (mPowerSaveTempWhitelistAppIds)
-    // for whitelisting, we can reuse their logic in this method.
+    // NOTE: since both fw_dozable and fw_powersave uses the same map
+    // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
     private void updateRulesForWhitelistedPowerSaveLocked(boolean enabled, int chain,
             SparseIntArray rules) {
         if (enabled) {
@@ -2433,8 +2453,8 @@
         enableFirewallChainLocked(chain, enabled);
     }
 
-    // NOTE: since both fw_dozable and fw_powersave uses the same map (mPowerSaveTempWhitelistAppIds)
-    // for whitelisting, we can reuse their logic in this method.
+    // NOTE: since both fw_dozable and fw_powersave uses the same map
+    // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
     private void updateRulesForWhitelistedPowerSaveLocked(int uid, boolean enabled, int chain) {
         if (enabled) {
             int appId = UserHandle.getAppId(uid);
@@ -2452,7 +2472,6 @@
         uidRules.clear();
 
         // Fully update the app idle firewall chain.
-        final IPackageManager ipm = AppGlobals.getPackageManager();
         final List<UserInfo> users = mUserManager.getUsers();
         for (int ui = users.size() - 1; ui >= 0; ui--) {
             UserInfo user = users.get(ui);
@@ -2499,7 +2518,7 @@
         updateRulesForDeviceIdleLocked();
         updateRulesForAppIdleLocked();
         updateRulesForRestrictPowerLocked();
-        updateRulesForRestrictDataLocked();
+        updateRulesForRestrictBackgroundLocked();
 
         // If the set of restricted networks may have changed, re-evaluate those.
         if (restrictedNetworksChanged) {
@@ -2513,7 +2532,7 @@
         }
     }
 
-    private void updateRulesForRestrictDataLocked() {
+    private void updateRulesForRestrictBackgroundLocked() {
         final PackageManager pm = mContext.getPackageManager();
 
         // update rules for all installed applications
@@ -2530,13 +2549,13 @@
             for (int j = 0; j < appsSize; j++) {
                 final ApplicationInfo app = apps.get(j);
                 final int uid = UserHandle.getUid(user.id, app.uid);
-                updateRestrictDataRulesForUidLocked(uid);
+                updateRuleForRestrictBackgroundLocked(uid);
             }
         }
 
         // limit data usage for some internal system services
-        updateRestrictDataRulesForUidLocked(android.os.Process.MEDIA_UID);
-        updateRestrictDataRulesForUidLocked(android.os.Process.DRM_UID);
+        updateRuleForRestrictBackgroundLocked(android.os.Process.MEDIA_UID);
+        updateRuleForRestrictBackgroundLocked(android.os.Process.DRM_UID);
     }
 
     private void updateRulesForTempWhitelistChangeLocked() {
@@ -2548,15 +2567,15 @@
                 int uid = UserHandle.getUid(user.id, appId);
                 updateRuleForAppIdleLocked(uid);
                 updateRuleForDeviceIdleLocked(uid);
-                updateRulesForRestrictPowerLocked(uid);
+                updateRuleForRestrictPowerLocked(uid);
             }
         }
     }
 
-    private static boolean isUidValidForRules(int uid) {
-        // allow rules on specific system services, and any apps
+    private boolean isUidValidForRules(int uid) {
+        // allow rules on specific system services, and any apps (that have network access)
         if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
-                || UserHandle.isApp(uid)) {
+                || (UserHandle.isApp(uid) && hasInternetPermissions(uid))) {
             return true;
         }
 
@@ -2594,12 +2613,21 @@
     }
 
     /**
-     * Applies network rules to bandwidth controllers based on uid policy.
+     * Applies network rules to bandwidth and firewall controllers based on uid policy.
      *
-     * @param uid The uid for which to apply the latest policy
+     * <p>There are currently 2 types of restriction rules:
+     * <ul>
+     * <li>Battery Saver Mode (also referred as power save).
+     * <li>Data Saver Mode (formerly known as restrict background data).
+     * </ul>
      */
-    private void updateRestrictDataRulesForUidLocked(int uid) {
-        if (!isUidValidForRules(uid) || !hasInternetPermissions(uid)) return;
+    private void updateRestrictionRulesForUidLocked(int uid) {
+        updateRuleForRestrictPowerLocked(uid);
+        updateRuleForRestrictBackgroundLocked(uid);
+    }
+
+    private void updateRuleForRestrictBackgroundLocked(int uid) {
+        if (!isUidValidForRules(uid)) return;
 
         final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
         final boolean uidForeground = isUidForegroundLocked(uid);
@@ -2618,8 +2646,10 @@
         }
 
         final int oldRule = mUidRules.get(uid);
-        if (LOGV) Log.v(TAG, "updateBandwithControllerRulesForUidLocked(" + uid + "): oldRule = "
-                + oldRule + ", newRule = " + newRule);
+        if (LOGV) {
+            Log.v(TAG, "updateRulesForRestrictBackgroundLocked(" + uid + "): oldRule = "
+                + ruleToString(oldRule) + ", newRule = " + ruleToString(newRule));
+        }
 
         if (newRule == RULE_ALLOW_ALL) {
             mUidRules.delete(uid);
@@ -2627,20 +2657,14 @@
             mUidRules.put(uid, newRule);
         }
 
-        final boolean rejectMetered = (newRule == RULE_REJECT_METERED);
-        setUidNetworkRules(uid, rejectMetered);
-
-        // dispatch changed rule to existing listeners
         if (oldRule != newRule) {
+            final boolean rejectMetered = (newRule == RULE_REJECT_METERED);
+            setUidNetworkRules(uid, rejectMetered);
+
+            // dispatch changed rule to existing listeners
             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newRule).sendToTarget();
         }
 
-        try {
-            // adjust stats accounting based on foreground status
-            mNetworkStats.setUidForeground(uid, uidForeground);
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
-        }
     }
 
     private class AppIdleStateChangeListener
@@ -2803,7 +2827,7 @@
 
     private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
         try {
-            mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
+            mNetworkManager.setUidMeteredNetworkBlacklist(uid, rejectOnQuotaInterfaces);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem setting uid rules", e);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/net/NetworkStatsObservers.java b/services/core/java/com/android/server/net/NetworkStatsObservers.java
index 2f55562..6f781b3 100644
--- a/services/core/java/com/android/server/net/NetworkStatsObservers.java
+++ b/services/core/java/com/android/server/net/NetworkStatsObservers.java
@@ -52,7 +52,7 @@
  */
 class NetworkStatsObservers {
     private static final String TAG = "NetworkStatsObservers";
-    private static final boolean LOGV = true;
+    private static final boolean LOGV = false;
 
     private static final long MIN_THRESHOLD_BYTES = 2 * MB_IN_BYTES;
 
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 0eacd13..eae2eaa 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -24,7 +24,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.ServiceManager;
-import android.os.SystemProperties;
 import android.util.ArraySet;
 import android.util.Log;
 
@@ -51,8 +50,6 @@
 
     final AtomicBoolean mIdleTime = new AtomicBoolean(false);
 
-    private boolean useJitProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
-
     public static void schedule(Context context) {
         JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
         JobInfo job = new JobInfo.Builder(BACKGROUND_DEXOPT_JOB, sDexoptServiceName)
@@ -93,8 +90,8 @@
                         // skip previously failing package
                         continue;
                     }
-                    if (!pm.performDexOpt(pkg, /* instruction set */ null, useJitProfiles,
-                            /* extractOnly */ false, /* force */ false)) {
+                    if (!pm.performDexOpt(pkg, /* instruction set */ null, /* checkProfiles */ true,
+                            PackageManagerService.REASON_BACKGROUND_DEXOPT, /* force */ false)) {
                         // there was a problem running dexopt,
                         // remember this so we do not keep retrying.
                         sFailedPackageNames.add(pkg);
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 206a143..7e25632 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.pm.PackageStats;
 import android.os.Build;
-import android.os.storage.StorageManager;
 import android.util.Slog;
 
 import com.android.internal.os.InstallerConnection;
@@ -37,17 +36,17 @@
      * frameworks/native/cmds/installd/installd.h
      * **************************************************************************/
     /** Application should be visible to everyone */
-    public static final int DEXOPT_PUBLIC       = 1 << 1;
+    public static final int DEXOPT_PUBLIC         = 1 << 1;
     /** Application wants to run in VM safe mode */
-    public static final int DEXOPT_SAFEMODE     = 1 << 2;
+    public static final int DEXOPT_SAFEMODE       = 1 << 2;
     /** Application wants to allow debugging of its code */
-    public static final int DEXOPT_DEBUGGABLE   = 1 << 3;
+    public static final int DEXOPT_DEBUGGABLE     = 1 << 3;
     /** The system boot has finished */
-    public static final int DEXOPT_BOOTCOMPLETE = 1 << 4;
-    /** Do not compile, only extract bytecode into an OAT file */
-    public static final int DEXOPT_EXTRACTONLY  = 1 << 5;
+    public static final int DEXOPT_BOOTCOMPLETE   = 1 << 4;
+    /** Hint that the dexopt type is profile-guided. */
+    public static final int DEXOPT_PROFILE_GUIDED = 1 << 5;
     /** This is an OTA update dexopt */
-    public static final int DEXOPT_OTA          = 1 << 6;
+    public static final int DEXOPT_OTA            = 1 << 6;
 
     // NOTE: keep in sync with installd
     public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
@@ -137,19 +136,23 @@
     }
 
     public void dexopt(String apkPath, int uid, String instructionSet, int dexoptNeeded,
-            int dexFlags, String volumeUuid, boolean useProfiles) throws InstallerException {
+            int dexFlags, String compilerFilter, String volumeUuid) throws InstallerException {
         assertValidInstructionSet(instructionSet);
         mInstaller.dexopt(apkPath, uid, instructionSet, dexoptNeeded, dexFlags,
-                volumeUuid, useProfiles);
+                compilerFilter, volumeUuid);
     }
 
     public void dexopt(String apkPath, int uid, String pkgName, String instructionSet,
             int dexoptNeeded, @Nullable String outputPath, int dexFlags,
-            String volumeUuid, boolean useProfiles)
+            String compilerFilter, String volumeUuid)
                     throws InstallerException {
         assertValidInstructionSet(instructionSet);
         mInstaller.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded,
-                outputPath, dexFlags, volumeUuid, useProfiles);
+                outputPath, dexFlags, compilerFilter, volumeUuid);
+    }
+
+    public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
+        return mInstaller.mergeProfiles(uid, pkgName);
     }
 
     public void idmap(String targetApkPath, String overlayApkPath, int uid)
@@ -166,8 +169,12 @@
         mInstaller.execute("rmpackagedir", packageDir);
     }
 
-    public void rmProfiles(String pkgName) throws InstallerException {
-        mInstaller.execute("rmprofiles", pkgName);
+    public void clearAppProfiles(String pkgName) throws InstallerException {
+        mInstaller.execute("clear_app_profiles", pkgName);
+    }
+
+    public void destroyAppProfiles(String pkgName) throws InstallerException {
+        mInstaller.execute("destroy_app_profiles", pkgName);
     }
 
     public void createUserConfig(int userid) throws InstallerException {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 2f0532a..c303ceb 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -42,6 +42,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IInterface;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteCallbackList;
@@ -54,6 +55,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -102,6 +104,8 @@
 
         private final MyPackageMonitor mPackageMonitor = new MyPackageMonitor();
 
+        private final Handler mCallbackHandler;
+
         public LauncherAppsImpl(Context context) {
             mContext = context;
             mPm = mContext.getPackageManager();
@@ -109,6 +113,7 @@
             mShortcutServiceInternal = Preconditions.checkNotNull(
                     LocalServices.getService(ShortcutServiceInternal.class));
             mShortcutServiceInternal.addListener(mPackageMonitor);
+            mCallbackHandler = BackgroundThread.getHandler();
         }
 
         @VisibleForTesting
@@ -165,7 +170,7 @@
          * Register a receiver to watch for package broadcasts
          */
         private void startWatchingPackageBroadcasts() {
-            mPackageMonitor.register(mContext, null, UserHandle.ALL, true);
+            mPackageMonitor.register(mContext, UserHandle.ALL, true, mCallbackHandler);
         }
 
         /**
@@ -550,8 +555,9 @@
             }
         }
 
+        @VisibleForTesting
         void postToPackageMonitorHandler(Runnable r) {
-            mPackageMonitor.getRegisteredHandler().post(r);
+            mCallbackHandler.post(r);
         }
 
         private class MyPackageMonitor extends PackageMonitor implements ShortcutChangeListener {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 67aeed1..c3a9226 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -19,11 +19,11 @@
 import static com.android.server.pm.Installer.DEXOPT_OTA;
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
 
 import android.content.Context;
 import android.content.pm.IOtaDexopt;
 import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.Package;
 import android.os.Environment;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -130,6 +130,7 @@
         // TODO: If apps are not installed in the internal /data partition, we should compare
         //       against that storage's free capacity.
         File dataDir = Environment.getDataDirectory();
+        @SuppressWarnings("deprecation")
         long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
         if (lowThreshold == 0) {
             throw new IllegalStateException("Invalid low memory threshold");
@@ -142,7 +143,7 @@
         }
 
         mPackageDexOptimizer.performDexOpt(nextPackage, null /* ISAs */, false /* useProfiles */,
-                false /* extractOnly */);
+                getCompilerFilterForReason(PackageManagerService.REASON_AB_OTA));
     }
 
     private void moveAbArtifacts(Installer installer) {
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 561682c..4ca615d 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -20,13 +20,10 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.Package;
 import android.os.Environment;
 import android.os.PowerManager;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.os.storage.StorageManager;
-import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
 
@@ -34,18 +31,18 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
 
 import dalvik.system.DexFile;
 
 import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE;
 import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
+import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED;
 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
 import static com.android.server.pm.Installer.DEXOPT_SAFEMODE;
-import static com.android.server.pm.Installer.DEXOPT_EXTRACTONLY;
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
 
 /**
  * Helper class for running dexopt command on packages.
@@ -59,8 +56,6 @@
     static final int DEX_OPT_DEFERRED = 2;
     static final int DEX_OPT_FAILED = -1;
 
-    private static final boolean DEBUG_DEXOPT = PackageManagerService.DEBUG_DEXOPT;
-
     private final Installer mInstaller;
     private final Object mInstallLock;
 
@@ -94,8 +89,8 @@
      * <p>Calls to {@link com.android.server.pm.Installer#dexopt} on {@link #mInstaller} are
      * synchronized on {@link #mInstallLock}.
      */
-    int performDexOpt(PackageParser.Package pkg, String[] instructionSets, boolean useProfiles,
-            boolean extractOnly) {
+    int performDexOpt(PackageParser.Package pkg, String[] instructionSets, boolean checkProfiles,
+            String targetCompilationFilter) {
         synchronized (mInstallLock) {
             final boolean useLock = mSystemReady;
             if (useLock) {
@@ -103,7 +98,8 @@
                 mDexoptWakeLock.acquire();
             }
             try {
-                return performDexOptLI(pkg, instructionSets, useProfiles, extractOnly);
+                return performDexOptLI(pkg, instructionSets, checkProfiles,
+                        targetCompilationFilter);
             } finally {
                 if (useLock) {
                     mDexoptWakeLock.release();
@@ -128,7 +124,7 @@
     }
 
     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
-            boolean useProfiles, boolean extractOnly) {
+            boolean checkProfiles, String targetCompilerFilter) {
         final String[] instructionSets = targetInstructionSets != null ?
                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
 
@@ -136,36 +132,50 @@
             return DEX_OPT_SKIPPED;
         }
 
+        final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
+        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+
+        boolean isProfileGuidedFilter = DexFile.isProfileGuidedCompilerFilter(targetCompilerFilter);
+        // If any part of the app is used by other apps, we cannot use profile-guided
+        // compilation.
+        // Skip the check for forward locked packages since they don't share their code.
+        if (isProfileGuidedFilter && !pkg.isForwardLocked()) {
+            for (String path : paths) {
+                if (isUsedByOtherApps(path)) {
+                    checkProfiles = false;
+
+                    // TODO: Should we only upgrade to the non-profile-guided version? That is,
+                    //       given verify-profile, should we move to interpret-only?
+                    targetCompilerFilter = getFullCompilerFilter();
+                    isProfileGuidedFilter = false;
+
+                    break;
+                }
+            }
+        }
+
+        // If we're asked to take profile updates into account, check now.
+        boolean newProfile = false;
+        if (checkProfiles && isProfileGuidedFilter) {
+            // Merge profiles, see if we need to do anything.
+            try {
+                newProfile = mInstaller.mergeProfiles(sharedGid, pkg.packageName);
+            } catch (InstallerException e) {
+                Slog.w(TAG, "Failed to merge profiles", e);
+            }
+        }
+
         final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
         final boolean debuggable = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
 
-        final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
         boolean performedDexOpt = false;
         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
             for (String path : paths) {
-                if (useProfiles && isUsedByOtherApps(path)) {
-                    // We cannot use profile guided compilation if the apk was used by another app.
-                    useProfiles = false;
-                }
                 int dexoptNeeded;
-
                 try {
-                    int compilationTypeMask = 0;
-                    if (extractOnly) {
-                        // For extract only, any type of compilation is good.
-                        compilationTypeMask = DexFile.COMPILATION_TYPE_FULL
-                            | DexFile.COMPILATION_TYPE_PROFILE_GUIDE
-                            | DexFile.COMPILATION_TYPE_EXTRACT_ONLY;
-                    } else {
-                        // Branch taken for profile guide and full compilation.
-                        // Profile guide compilation should only recompile a previous
-                        // profile compiled/extract only file and should not be attempted if the
-                        // apk is already fully compiled. So test against a full compilation type.
-                        compilationTypeMask = DexFile.COMPILATION_TYPE_FULL;
-                    }
                     dexoptNeeded = DexFile.getDexOptNeeded(path,
-                            dexCodeInstructionSet, compilationTypeMask);
+                            dexCodeInstructionSet, targetCompilerFilter, newProfile);
                 } catch (IOException ioe) {
                     Slog.w(TAG, "IOException reading apk: " + path, ioe);
                     return DEX_OPT_FAILED;
@@ -194,20 +204,20 @@
                 Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
                         + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
                         + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
-                        + " extractOnly=" + extractOnly + " oatDir = " + oatDir);
-                final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+                        + " target-filter=" + targetCompilerFilter + " oatDir = " + oatDir);
                 // Profile guide compiled oat files should not be public.
-                final boolean isPublic = !pkg.isForwardLocked() && !useProfiles;
+                final boolean isPublic = !pkg.isForwardLocked() && !isProfileGuidedFilter;
+                final int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0;
                 final int dexFlags = adjustDexoptFlags(
                         ( isPublic ? DEXOPT_PUBLIC : 0)
                         | (vmSafeMode ? DEXOPT_SAFEMODE : 0)
                         | (debuggable ? DEXOPT_DEBUGGABLE : 0)
-                        | (extractOnly ? DEXOPT_EXTRACTONLY : 0)
+                        | profileFlag
                         | DEXOPT_BOOTCOMPLETE);
 
                 try {
                     mInstaller.dexopt(path, sharedGid, pkg.packageName, dexCodeInstructionSet,
-                            dexoptNeeded, oatDir, dexFlags, pkg.volumeUuid, useProfiles);
+                            dexoptNeeded, oatDir, dexFlags, targetCompilerFilter, pkg.volumeUuid);
                     performedDexOpt = true;
                 } catch (InstallerException e) {
                     Slog.w(TAG, "Failed to dexopt", e);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9335116..d2fd762 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -92,6 +92,8 @@
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
@@ -441,6 +443,18 @@
         sBrowserIntent.setData(Uri.parse("http:"));
     }
 
+    // Compilation reasons.
+    public static final int REASON_FIRST_BOOT = 0;
+    public static final int REASON_BOOT = 1;
+    public static final int REASON_INSTALL = 2;
+    public static final int REASON_BACKGROUND_DEXOPT = 3;
+    public static final int REASON_AB_OTA = 4;
+    public static final int REASON_NON_SYSTEM_LIBRARY = 5;
+    public static final int REASON_SHARED_APK = 6;
+    public static final int REASON_FORCED_DEXOPT = 7;
+
+    public static final int REASON_LAST = REASON_FORCED_DEXOPT;
+
     final ServiceThread mHandlerThread;
 
     final PackageHandler mHandler;
@@ -460,6 +474,7 @@
     final int mDefParseFlags;
     final String[] mSeparateProcesses;
     final boolean mIsUpgrade;
+    final boolean mIsPreNUpgrade;
 
     /** The location for ASEC container files on internal storage. */
     final String mAsecInternalPath;
@@ -1956,6 +1971,9 @@
 
     public static PackageManagerService main(Context context, Installer installer,
             boolean factoryTest, boolean onlyCore) {
+        // Self-check for initial settings.
+        PackageManagerServiceCompilerMapping.checkProperties();
+
         PackageManagerService m = new PackageManagerService(context, installer,
                 factoryTest, onlyCore);
         m.enableSystemUserPackages();
@@ -2168,12 +2186,13 @@
                             // AOT compilation (if needed).
                             int dexoptNeeded = DexFile.getDexOptNeeded(
                                     lib, dexCodeInstructionSet,
-                                    DexFile.COMPILATION_TYPE_FULL);
+                                    getCompilerFilterForReason(REASON_SHARED_APK),
+                                    false /* newProfile */);
                             if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
                                         dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
-                                        StorageManager.UUID_PRIVATE_INTERNAL,
-                                        false /*useProfiles*/);
+                                        getCompilerFilterForReason(REASON_SHARED_APK),
+                                        StorageManager.UUID_PRIVATE_INTERNAL);
                             }
                         } catch (FileNotFoundException e) {
                             Slog.w(TAG, "Library not found: " + lib);
@@ -2189,6 +2208,7 @@
 
             final VersionInfo ver = mSettings.getInternalVersion();
             mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
+
             // when upgrading from pre-M, promote system app permissions from install to runtime
             mPromoteSystemApps =
                     mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
@@ -2205,6 +2225,11 @@
                 }
             }
 
+            // When upgrading from pre-N, we need to handle package extraction like first boot,
+            // as there is no profiling data available.
+            mIsPreNUpgrade = !mSettings.isNWorkDone();
+            mSettings.setNWorkDone();
+
             // Collect vendor overlay packages.
             // (Do this before scanning any apps.)
             // For security and version matching reason, only consider
@@ -2882,6 +2907,11 @@
                 throw new SecurityException("Package " + packageName + " was not found!");
             }
 
+            if (!ps.getInstalled(userId)) {
+                throw new SecurityException(
+                        "Package " + packageName + " was not installed for user " + userId + "!");
+            }
+
             if (mSafeMode && !ps.isSystem()) {
                 throw new SecurityException("Package " + packageName + " not a system app!");
             }
@@ -6893,10 +6923,18 @@
     public void extractPackagesIfNeeded() {
         enforceSystemOrRoot("Only the system can request package extraction");
 
-        // Extract pacakges only if profile-guided compilation is enabled because
-        // otherwise BackgroundDexOptService will not dexopt them later.
-        boolean prunedCache = VMRuntime.didPruneDalvikCache();
-        if (!isUpgrade() && !prunedCache) {
+        // We need to re-extract after an OTA.
+        boolean causeUpgrade = isUpgrade();
+
+        // First boot or factory reset.
+        // Note: we also handle devices that are upgrading to N right now as if it is their
+        //       first boot, as they do not have profile data.
+        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
+
+        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
+        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
+
+        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
             return;
         }
 
@@ -6928,7 +6966,9 @@
                 // and would have to be patched (would be SELF_PATCHOAT, which is deprecated).
                 // Instead, force the extraction in this case.
                 performDexOpt(pkg.packageName, null /* instructionSet */,
-                         false /* useProfiles */, true /* extractOnly */, prunedCache);
+                         false /* checkProfiles */,
+                         causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
+                         causePrunedCache);
             }
         }
     }
@@ -6947,29 +6987,37 @@
     // TODO: this is not used nor needed. Delete it.
     @Override
     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
-        return performDexOptTraced(packageName, instructionSet, false /* useProfiles */,
-                false /* extractOnly */, false /* force */);
+        return performDexOptTraced(packageName, instructionSet, false /* checkProfiles */,
+                getFullCompilerFilter(), false /* force */);
     }
 
     @Override
-    public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
-            boolean extractOnly, boolean force) {
-        return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly, force);
+    public boolean performDexOpt(String packageName, String instructionSet,
+            boolean checkProfiles, int compileReason, boolean force) {
+        return performDexOptTraced(packageName, instructionSet, checkProfiles,
+                getCompilerFilterForReason(compileReason), force);
+    }
+
+    @Override
+    public boolean performDexOptMode(String packageName, String instructionSet,
+            boolean checkProfiles, String targetCompilerFilter, boolean force) {
+        return performDexOptTraced(packageName, instructionSet, checkProfiles,
+                targetCompilerFilter, force);
     }
 
     private boolean performDexOptTraced(String packageName, String instructionSet,
-                boolean useProfiles, boolean extractOnly, boolean force) {
+                boolean checkProfiles, String targetCompilerFilter, boolean force) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
         try {
-            return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly,
-                    force);
+            return performDexOptInternal(packageName, instructionSet, checkProfiles,
+                    targetCompilerFilter, force);
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
     }
 
     private boolean performDexOptInternal(String packageName, String instructionSet,
-                boolean useProfiles, boolean extractOnly, boolean force) {
+                boolean checkProfiles, String targetCompilerFilter, boolean force) {
         PackageParser.Package p;
         final String targetInstructionSet;
         synchronized (mPackages) {
@@ -6987,7 +7035,7 @@
             synchronized (mInstallLock) {
                 final String[] instructionSets = new String[] { targetInstructionSet };
                 int result = performDexOptInternalWithDependenciesLI(p, instructionSets,
-                        useProfiles, extractOnly, force);
+                        checkProfiles, targetCompilerFilter, force);
                 return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
             }
         } finally {
@@ -7008,7 +7056,8 @@
     }
 
     private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
-            String instructionSets[], boolean useProfiles, boolean extractOnly, boolean force) {
+            String instructionSets[], boolean checkProfiles, String targetCompilerFilter,
+            boolean force) {
         // Select the dex optimizer based on the force parameter.
         // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
         //       allocate an object here.
@@ -7022,13 +7071,13 @@
         if (!deps.isEmpty()) {
             for (PackageParser.Package depPackage : deps) {
                 // TODO: Analyze and investigate if we (should) profile libraries.
-                // Currently this will do a full compilation of the library.
-                pdo.performDexOpt(depPackage, instructionSets, false /* useProfiles */,
-                        false /* extractOnly */);
+                // Currently this will do a full compilation of the library by default.
+                pdo.performDexOpt(depPackage, instructionSets, false /* checkProfiles */,
+                        getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY));
             }
         }
 
-        return pdo.performDexOpt(p, instructionSets, useProfiles, extractOnly);
+        return pdo.performDexOpt(p, instructionSets, checkProfiles, targetCompilerFilter);
     }
 
     Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
@@ -7106,7 +7155,8 @@
             // Whoever is calling forceDexOpt wants a fully compiled package.
             // Don't use profiles since that may cause compilation to be skipped.
             final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets,
-                    false /* useProfiles */, false /* extractOnly */, true /* force */);
+                    false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
+                    true /* force */);
 
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -7176,6 +7226,30 @@
         }
     }
 
+    private void deleteProfilesLI(String packageName, boolean destroy) {
+        final PackageParser.Package pkg;
+        synchronized (mPackages) {
+            pkg = mPackages.get(packageName);
+        }
+        if (pkg == null) {
+            Slog.w(TAG, "Failed to delete profiles. No package: " + packageName);
+            return;
+        }
+        deleteProfilesLI(pkg, destroy);
+    }
+
+    private void deleteProfilesLI(PackageParser.Package pkg, boolean destroy) {
+        try {
+            if (destroy) {
+                mInstaller.clearAppProfiles(pkg.packageName);
+            } else {
+                mInstaller.destroyAppProfiles(pkg.packageName);
+            }
+        } catch (InstallerException ex) {
+            Log.e(TAG, "Could not delete profiles for package " + pkg.packageName);
+        }
+    }
+
     private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
         final PackageParser.Package pkg;
         synchronized (mPackages) {
@@ -13079,6 +13153,7 @@
         final PackageParser.Package oldPackage;
         final String pkgName = pkg.packageName;
         final int[] allUsers;
+        final boolean weFroze;
 
         // First find the old package info and check signatures
         synchronized(mPackages) {
@@ -13111,8 +13186,32 @@
 
             // In case of rollback, remember per-user/profile install state
             allUsers = sUserManager.getUserIds();
+
+            // Mark the app as frozen to prevent launching during the upgrade
+            // process, and then kill all running instances
+            if (!ps.frozen) {
+                ps.frozen = true;
+                weFroze = true;
+            } else {
+                weFroze = false;
+            }
         }
 
+        try {
+            replacePackageDirtyLI(pkg, oldPackage, parseFlags, scanFlags, user, allUsers,
+                    installerPackageName, res);
+        } finally {
+            // Regardless of success or failure of upgrade steps above, always
+            // unfreeze the package if we froze it
+            if (weFroze) {
+                unfreezePackage(pkgName);
+            }
+        }
+    }
+
+    private void replacePackageDirtyLI(PackageParser.Package pkg, PackageParser.Package oldPackage,
+            int parseFlags, int scanFlags, UserHandle user, int[] allUsers,
+            String installerPackageName, PackageInstalledInfo res) {
         // Update what is removed
         res.removedInfo = new PackageRemovedInfo();
         res.removedInfo.uid = oldPackage.applicationInfo.uid;
@@ -13208,6 +13307,7 @@
             }
 
             deleteCodeCacheDirsLI(pkg);
+            deleteProfilesLI(pkg, /*destroy*/ false);
 
             try {
                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
@@ -13342,6 +13442,7 @@
 
         // Successfully disabled the old package. Now proceed with re-installation
         deleteCodeCacheDirsLI(pkg);
+        deleteProfilesLI(pkg, /*destroy*/ false);
 
         res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
         pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
@@ -13973,7 +14074,7 @@
             // Do not run PackageDexOptimizer through the local performDexOpt
             // method because `pkg` is not in `mPackages` yet.
             int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
-                    false /* useProfiles */, true /* extractOnly */);
+                    false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL));
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
                 String msg = "Extracking package failed for " + pkgName;
@@ -14414,6 +14515,7 @@
             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
             res = deletePackageLI(packageName, removeForUser, true, allUsers,
                     flags | REMOVE_CHATTY, info, true, null);
+            deleteProfilesLI(packageName, /*destroy*/ true);
             synchronized (mPackages) {
                 if (res) {
                     mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
@@ -15181,7 +15283,7 @@
     public void clearApplicationProfileData(String packageName) {
         enforceSystemOrRoot("Only the system can clear all profile data");
         try {
-            mInstaller.rmProfiles(packageName);
+            mInstaller.clearAppProfiles(packageName);
         } catch (InstallerException ex) {
             Log.e(TAG, "Could not clear profile data of package " + packageName);
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
new file mode 100644
index 0000000..f1b7991
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.os.SystemProperties;
+
+import dalvik.system.DexFile;
+
+/**
+ * Manage (retrieve) mappings from compilation reason to compilation filter.
+ */
+class PackageManagerServiceCompilerMapping {
+    // Names for compilation reasons.
+    static final String REASON_STRINGS[] = {
+            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk",
+            "forced-dexopt"
+    };
+
+    // Static block to ensure the strings array is of the right length.
+    static {
+        if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) {
+            throw new IllegalStateException("REASON_STRINGS not correct");
+        }
+    }
+
+    private static String getSystemPropertyName(int reason) {
+        if (reason < 0 || reason >= REASON_STRINGS.length) {
+            throw new IllegalArgumentException("reason " + reason + " invalid");
+        }
+
+        return "pm.dexopt." + REASON_STRINGS[reason];
+    }
+
+    // Load the property for the given reason and check for validity. This will throw an
+    // exception in case the reason or value are invalid.
+    private static String getAndCheckValidity(int reason) {
+        String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
+        if (sysPropValue == null || sysPropValue.isEmpty() ||
+                !DexFile.isValidCompilerFilter(sysPropValue)) {
+            throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
+                    + "(reason " + REASON_STRINGS[reason] + ")");
+        }
+
+        // Ensure that some reasons are not mapped to profile-guided filters.
+        switch (reason) {
+            case PackageManagerService.REASON_SHARED_APK:
+            case PackageManagerService.REASON_FORCED_DEXOPT:
+                if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) {
+                    throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, "
+                            + "but not allowed for " + REASON_STRINGS[reason]);
+                }
+                break;
+        }
+
+        return sysPropValue;
+    }
+
+    // Check that the properties are set and valid.
+    // Note: this is done in a separate method so this class can be statically initialized.
+    static void checkProperties() {
+        // We're gonna check all properties and collect the exceptions, so we can give a general
+        // overview. Store the exceptions here.
+        RuntimeException toThrow = null;
+
+        for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) {
+            try {
+                // Check that the system property name is legal.
+                String sysPropName = getSystemPropertyName(reason);
+                if (sysPropName == null ||
+                        sysPropName.isEmpty() ||
+                        sysPropName.length() > SystemProperties.PROP_NAME_MAX) {
+                    throw new IllegalStateException("Reason system property name \"" +
+                            sysPropName +"\" for reason " + REASON_STRINGS[reason]);
+                }
+
+                // Check validity, ignore result.
+                getAndCheckValidity(reason);
+            } catch (Exception exc) {
+                if (toThrow == null) {
+                    toThrow = new IllegalStateException("PMS compiler filter settings are bad.");
+                }
+                toThrow.addSuppressed(exc);
+            }
+        }
+
+        if (toThrow != null) {
+            throw toThrow;
+        }
+    }
+
+    public static String getCompilerFilterForReason(int reason) {
+        return getAndCheckValidity(reason);
+    }
+
+    /**
+     * Return the compiler filter for "full" compilation.
+     *
+     * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make
+     * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values.
+     */
+    public static String getFullCompilerFilter() {
+        String value = SystemProperties.get("dalvik.vm.dex2oat-filter");
+        if (value == null || value.isEmpty()) {
+            return "speed";
+        }
+
+        if (!DexFile.isValidCompilerFilter(value) ||
+                DexFile.isProfileGuidedCompilerFilter(value)) {
+            return "speed";
+        }
+
+        return value;
+    }
+
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 319fc37..238ce95 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -50,6 +50,8 @@
 import android.util.PrintWriterPrinter;
 import com.android.internal.util.SizedInputStream;
 
+import dalvik.system.DexFile;
+
 import libcore.io.IoUtils;
 
 import java.io.File;
@@ -248,12 +250,42 @@
 
     private int runCompile() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
-        boolean useJitProfiles = false;
-        boolean extractOnly = false;
+        boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
         boolean forceCompilation = false;
         boolean allPackages = false;
         boolean clearProfileData = false;
-        String compilationMode = "default";
+        String compilerFilter = null;
+        String compilationReason = null;
+        String checkProfilesRaw = null;
+
+        if (peekNextArg() == null) {
+            // No arguments, show help.
+            pw.println("Usage: cmd package compile [-c] [-f] [--reset] [-m mode] " +
+                    "[-r reason] [-a|pkg]");
+            pw.println();
+            pw.println("  -c                Clear profile data");
+            pw.println("  -f                Force compilation");
+            pw.println("  --check-prof val  Look at profiles when doing dexopt.");
+            pw.println("                    Overrides dalvik.vm.usejitprofiles to true of false");
+            pw.println("  --reset           Reset package");
+            pw.println("  -m mode           Compilation mode, one of the dex2oat compiler filters");
+            pw.println("                      verify-none");
+            pw.println("                      verify-at-runtime");
+            pw.println("                      verify-profile");
+            pw.println("                      interpret-only");
+            pw.println("                      space-profile");
+            pw.println("                      space");
+            pw.println("                      speed-profile");
+            pw.println("                      speed");
+            pw.println("                      everything");
+            pw.println("  -r reason  Compiler reason, one of the package manager reasons");
+            for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
+                pw.println("               " +
+                        PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
+            }
+            pw.println("  -a         Apply to all packages");
+            return 1;
+        }
 
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -268,12 +300,18 @@
                     forceCompilation = true;
                     break;
                 case "-m":
-                    compilationMode = getNextArgRequired();
+                    compilerFilter = getNextArgRequired();
+                    break;
+                case "-r":
+                    compilationReason = getNextArgRequired();
+                    break;
+                case "-check-prof":
+                    checkProfilesRaw = getNextArgRequired();
                     break;
                 case "--reset":
                     forceCompilation = true;
                     clearProfileData = true;
-                    compilationMode = "extract";
+                    compilerFilter = "reset";
                     break;
                 default:
                     pw.println("Error: Unknown option: " + opt);
@@ -281,28 +319,67 @@
             }
         }
 
-        switch (compilationMode) {
-            case "default":
-                useJitProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
-                extractOnly = false;
-                break;
-            case "full":
-                useJitProfiles = false;
-                extractOnly = false;
-                break;
-            case "profile":
-                useJitProfiles = true;
-                extractOnly = false;
-                break;
-            case "extract":
-                useJitProfiles = false;
-                extractOnly = true;
-                break;
-            default:
-                pw.println("Error: Unknown compilation mode: " + compilationMode);
+        if (checkProfilesRaw != null) {
+            if ("true".equals(checkProfilesRaw)) {
+                checkProfiles = true;
+            } else if ("false".equals(checkProfilesRaw)) {
+                checkProfiles = false;
+            } else {
+                pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
                 return 1;
+            }
         }
 
+        if (compilerFilter != null && compilationReason != null) {
+            pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
+                    "at the same time");
+            return 1;
+        }
+        if (compilerFilter == null && compilationReason == null) {
+            pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
+                    "reason (\"-r\") at the same time");
+            return 1;
+        }
+
+        String targetCompilerFilter;
+        if (compilerFilter != null) {
+            // Specially recognize default and reset. Otherwise, only accept valid modes.
+            if ("default".equals(compilerFilter)) {
+                // Use the default mode for background dexopt.
+                targetCompilerFilter =
+                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
+                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
+            } else if ("reset".equals(compilerFilter)) {
+                // Use the default mode for install.
+                targetCompilerFilter =
+                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
+                                PackageManagerService.REASON_INSTALL);
+            } else {
+                if (!DexFile.isValidCompilerFilter(compilerFilter)) {
+                    pw.println("Error: \"" + compilerFilter +
+                            "\" is not a valid compilation filter.");
+                    return 1;
+                }
+                targetCompilerFilter = compilerFilter;
+            }
+        } else {
+            int reason = -1;
+            for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
+                if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
+                        compilationReason)) {
+                    reason = i;
+                    break;
+                }
+            }
+            if (reason == -1) {
+                pw.println("Error: Unknown compilation reason: " + compilationReason);
+                return 1;
+            }
+            targetCompilerFilter =
+                    PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
+        }
+
+
         List<String> packageNames = null;
         if (allPackages) {
             packageNames = mInterface.getAllPackages();
@@ -321,8 +398,8 @@
                 mInterface.clearApplicationProfileData(packageName);
             }
 
-            boolean result = mInterface.performDexOpt(packageName, null /* instructionSet */,
-                        useJitProfiles, extractOnly, forceCompilation);
+            boolean result = mInterface.performDexOptMode(packageName, null /* instructionSet */,
+                    checkProfiles, targetCompilerFilter, forceCompilation);
             if (!result) {
                 failedPackages.add(packageName);
             }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index e66ec3c..3c3c576 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -190,6 +190,7 @@
             "all-intent-filter-verifications";
     private static final String TAG_DEFAULT_BROWSER = "default-browser";
     private static final String TAG_VERSION = "version";
+    private static final String TAG_N_WORK = "n-work";
 
     private static final String ATTR_NAME = "name";
     private static final String ATTR_USER = "user";
@@ -214,6 +215,7 @@
     private static final String ATTR_VOLUME_UUID = "volumeUuid";
     private static final String ATTR_SDK_VERSION = "sdkVersion";
     private static final String ATTR_DATABASE_VERSION = "databaseVersion";
+    private static final String ATTR_DONE = "done";
 
     // Bookkeeping for restored permission grants
     private static final String TAG_RESTORED_RUNTIME_PERMISSIONS = "restored-perms";
@@ -386,6 +388,17 @@
 
     public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
 
+    /**
+     * Used to track whether N+ work has been done. This is similar to the file-system level
+     * and denotes that first-boot or upgrade-to-N work has been done.
+     *
+     * Note: the flag has been added to a) allow tracking while an API level check is impossible
+     *       and b) to merge upgrade as well as first boot (because the flag is false, by default).
+     *
+     * STOPSHIP: b/27872764
+     */
+    private boolean mIsNWorkDone = false;
+
     Settings(Object lock) {
         this(Environment.getDataDirectory(), lock);
     }
@@ -2327,6 +2340,10 @@
 
             mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
 
+            serializer.startTag(null, TAG_N_WORK);
+            serializer.attribute(null, ATTR_DONE, Boolean.toString(mIsNWorkDone));
+            serializer.endTag(null, TAG_N_WORK);
+
             serializer.endTag(null, "packages");
 
             serializer.endDocument();
@@ -2860,7 +2877,8 @@
                     ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
                     ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
                     ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
-
+                } else if (TAG_N_WORK.equals(tagName)) {
+                    mIsNWorkDone = XmlUtils.readBooleanAttribute(parser, ATTR_DONE, false);
                 } else {
                     Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
                             + parser.getName());
@@ -4140,6 +4158,14 @@
         return res;
     }
 
+    public boolean isNWorkDone() {
+        return mIsNWorkDone;
+    }
+
+    void setNWorkDone() {
+        mIsNWorkDone = true;
+    }
+
     static void printFlags(PrintWriter pw, int val, Object[] spec) {
         pw.print("[ ");
         for (int i=0; i<spec.length; i+=2) {
@@ -4456,7 +4482,8 @@
             }
         }
 
-        if ((permissionNames != null || dumpAll) && ps.pkg.requestedPermissions != null
+        if ((permissionNames != null || dumpAll) && ps.pkg != null
+                && ps.pkg.requestedPermissions != null
                 && ps.pkg.requestedPermissions.size() > 0) {
             final ArrayList<String> perms = ps.pkg.requestedPermissions;
             pw.print(prefix); pw.println("  requested permissions:");
diff --git a/services/core/java/com/android/server/pm/ShortcutBackupAgent.java b/services/core/java/com/android/server/pm/ShortcutBackupAgent.java
new file mode 100644
index 0000000..a0fbc37
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutBackupAgent.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import android.app.backup.BlobBackupHelper;
+
+public class ShortcutBackupAgent extends BlobBackupHelper {
+    private static final String TAG = "ShortcutBackupAgent";
+    private static final int BLOB_VERSION = 1;
+
+    public ShortcutBackupAgent(int currentBlobVersion, String... keys) {
+        super(currentBlobVersion, keys);
+    }
+
+    @Override
+    protected byte[] getBackupPayload(String key) {
+        throw new RuntimeException("not implemented yet"); // todo
+    }
+
+    @Override
+    protected void applyRestoredPayload(String key, byte[] payload) {
+        throw new RuntimeException("not implemented yet"); // todo
+    }
+}
diff --git a/services/core/java/com/android/server/pm/ShortcutLauncher.java b/services/core/java/com/android/server/pm/ShortcutLauncher.java
index f1920c7..740a8f7 100644
--- a/services/core/java/com/android/server/pm/ShortcutLauncher.java
+++ b/services/core/java/com/android/server/pm/ShortcutLauncher.java
@@ -32,7 +32,7 @@
 /**
  * Launcher information used by {@link ShortcutService}.
  */
-class ShortcutLauncher {
+class ShortcutLauncher implements ShortcutPackageItem {
     private static final String TAG = ShortcutService.TAG;
 
     static final String TAG_ROOT = "launcher-pins";
@@ -44,10 +44,10 @@
     private static final String ATTR_PACKAGE_NAME = "package-name";
 
     @UserIdInt
-    final int mUserId;
+    private final int mUserId;
 
     @NonNull
-    final String mPackageName;
+    private final String mPackageName;
 
     /**
      * Package name -> IDs.
@@ -59,6 +59,16 @@
         mPackageName = packageName;
     }
 
+    @UserIdInt
+    public int getUserId() {
+        return mUserId;
+    }
+
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
     public void pinShortcuts(@NonNull ShortcutService s, @NonNull String packageName,
             @NonNull List<String> ids) {
         final int idSize = ids.size();
@@ -103,7 +113,7 @@
     /**
      * Persist.
      */
-    public void saveToXml(XmlSerializer out) throws IOException {
+    public void saveToXml(XmlSerializer out, boolean forBackup) throws IOException {
         final int size = mPinnedShortcuts.size();
         if (size == 0) {
             return; // Nothing to write.
@@ -190,7 +200,7 @@
 
             for (int j = 0; j < idSize; j++) {
                 pw.print(prefix);
-                pw.print("    ");
+                pw.print("    Pinned: ");
                 pw.print(ids.valueAt(j));
                 pw.println();
             }
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index d614251..359ea1c 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -41,7 +41,7 @@
 /**
  * Package information used by {@link ShortcutService}.
  */
-class ShortcutPackage {
+class ShortcutPackage implements ShortcutPackageItem {
     private static final String TAG = ShortcutService.TAG;
 
     static final String TAG_ROOT = "package";
@@ -64,10 +64,10 @@
     private static final String ATTR_BITMAP_PATH = "bitmap-path";
 
     @UserIdInt
-    final int mUserId;
+    private final int mUserId;
 
     @NonNull
-    final String mPackageName;
+    private final String mPackageName;
 
     /**
      * All the shortcuts from the package, keyed on IDs.
@@ -94,6 +94,16 @@
         mPackageName = packageName;
     }
 
+    @UserIdInt
+    public int getUserId() {
+        return mUserId;
+    }
+
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
     @Nullable
     public ShortcutInfo findShortcutById(String id) {
         return mShortcuts.get(id);
@@ -381,7 +391,8 @@
         pw.println(")");
     }
 
-    public void saveToXml(@NonNull XmlSerializer out) throws IOException, XmlPullParserException {
+    public void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
+            throws IOException, XmlPullParserException {
         final int size = mShortcuts.size();
 
         if (size == 0 && mApiCallCount == 0) {
@@ -396,14 +407,19 @@
         ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
 
         for (int j = 0; j < size; j++) {
-            saveShortcut(out, mShortcuts.valueAt(j));
+            saveShortcut(out, mShortcuts.valueAt(j), forBackup);
         }
 
         out.endTag(null, TAG_ROOT);
     }
 
-    private static void saveShortcut(XmlSerializer out, ShortcutInfo si)
+    private static void saveShortcut(XmlSerializer out, ShortcutInfo si, boolean forBackup)
             throws IOException, XmlPullParserException {
+        if (forBackup) {
+            if (!si.isPinned()) {
+                return; // Backup only pinned icons.
+            }
+        }
         out.startTag(null, TAG_SHORTCUT);
         ShortcutService.writeAttr(out, ATTR_ID, si.getId());
         // writeAttr(out, "package", si.getPackageName()); // not needed
@@ -414,9 +430,17 @@
         ShortcutService.writeAttr(out, ATTR_WEIGHT, si.getWeight());
         ShortcutService.writeAttr(out, ATTR_TIMESTAMP,
                 si.getLastChangedTimestamp());
-        ShortcutService.writeAttr(out, ATTR_FLAGS, si.getFlags());
-        ShortcutService.writeAttr(out, ATTR_ICON_RES, si.getIconResourceId());
-        ShortcutService.writeAttr(out, ATTR_BITMAP_PATH, si.getBitmapPath());
+        if (forBackup) {
+            // Don't write icon information.  Also drop the dynamic flag.
+            ShortcutService.writeAttr(out, ATTR_FLAGS,
+                    si.getFlags() &
+                            ~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
+                            | ShortcutInfo.FLAG_DYNAMIC));
+        } else {
+            ShortcutService.writeAttr(out, ATTR_FLAGS, si.getFlags());
+            ShortcutService.writeAttr(out, ATTR_ICON_RES, si.getIconResourceId());
+            ShortcutService.writeAttr(out, ATTR_BITMAP_PATH, si.getBitmapPath());
+        }
 
         ShortcutService.writeTagExtra(out, TAG_INTENT_EXTRAS,
                 si.getIntentPersistableExtras());
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
new file mode 100644
index 0000000..00ea679
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.util.Slog;
+
+import com.android.internal.util.Preconditions;
+
+import libcore.io.Base64;
+import libcore.util.HexEncoding;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Package information used by {@link android.content.pm.ShortcutManager} for backup / restore.
+ *
+ * TODO: The methods about signature hashes are copied from BackupManagerService, which is not
+ * visible here.  Unify the code.
+ */
+class ShortcutPackageInfo implements ShortcutPackageItem {
+    private static final String TAG = ShortcutService.TAG;
+
+    static final String TAG_ROOT = "package-info";
+    private static final String ATTR_NAME = "name";
+    private static final String ATTR_VERSION = "version";
+    private static final String ATTR_SHADOW = "shadow";
+
+    private static final String TAG_SIGNATURE = "signature";
+    private static final String ATTR_SIGNATURE_HASH = "hash";
+
+    public interface ShortcutPackageInfoHolder {
+        ShortcutPackageInfo getShortcutPackageInfo();
+    }
+
+    private final String mPackageName;
+
+    /**
+     * When true, this package information was restored from the previous device, and the app hasn't
+     * been installed yet.
+     */
+    private boolean mIsShadow;
+    private int mVersionCode;
+    private ArrayList<byte[]> mSigHashes;
+
+    private ShortcutPackageInfo(String packageName, int versionCode, ArrayList<byte[]> sigHashes,
+            boolean isShadow) {
+        mVersionCode = versionCode;
+        mIsShadow = isShadow;
+        mSigHashes = sigHashes;
+        mPackageName = Preconditions.checkNotNull(packageName);
+    }
+
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public boolean isShadow() {
+        return mIsShadow;
+    }
+
+    public boolean isInstalled() {
+        return !mIsShadow;
+    }
+
+    public void setShadow(boolean shadow) {
+        mIsShadow = shadow;
+    }
+
+    public int getVersionCode() {
+        return mVersionCode;
+    }
+
+    private static byte[] hashSignature(Signature sig) {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("SHA-256");
+            digest.update(sig.toByteArray());
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            Slog.w(TAG, "No SHA-256 algorithm found!");
+        }
+        return null;
+    }
+
+    private static ArrayList<byte[]> hashSignatureArray(Signature[] sigs) {
+        if (sigs == null) {
+            return null;
+        }
+
+        ArrayList<byte[]> hashes = new ArrayList<byte[]>(sigs.length);
+        for (Signature s : sigs) {
+            hashes.add(hashSignature(s));
+        }
+        return hashes;
+    }
+
+    private static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target) {
+        if (target == null) {
+            return false;
+        }
+
+        // If the target resides on the system partition, we allow it to restore
+        // data from the like-named package in a restore set even if the signatures
+        // do not match.  (Unlike general applications, those flashed to the system
+        // partition will be signed with the device's platform certificate, so on
+        // different phones the same system app will have different signatures.)
+        if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+            return true;
+        }
+
+        // Allow unsigned apps, but not signed on one device and unsigned on the other
+        // !!! TODO: is this the right policy?
+        Signature[] deviceSigs = target.signatures;
+        if ((storedSigHashes == null || storedSigHashes.size() == 0)
+                && (deviceSigs == null || deviceSigs.length == 0)) {
+            return true;
+        }
+        if (storedSigHashes == null || deviceSigs == null) {
+            return false;
+        }
+
+        // !!! TODO: this demands that every stored signature match one
+        // that is present on device, and does not demand the converse.
+        // Is this this right policy?
+        final int nStored = storedSigHashes.size();
+        final int nDevice = deviceSigs.length;
+
+        // hash each on-device signature
+        ArrayList<byte[]> deviceHashes = new ArrayList<byte[]>(nDevice);
+        for (int i = 0; i < nDevice; i++) {
+            deviceHashes.add(hashSignature(deviceSigs[i]));
+        }
+
+        // now ensure that each stored sig (hash) matches an on-device sig (hash)
+        for (int n = 0; n < nStored; n++) {
+            boolean match = false;
+            final byte[] storedHash = storedSigHashes.get(n);
+            for (int i = 0; i < nDevice; i++) {
+                if (Arrays.equals(storedHash, deviceHashes.get(i))) {
+                    match = true;
+                    break;
+                }
+            }
+            // match is false when no on-device sig matched one of the stored ones
+            if (!match) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public boolean canRestoreTo(PackageInfo target) {
+        if (target.versionCode < mVersionCode) {
+            Slog.w(TAG, String.format("Package current version %d < backed up version %d",
+                    target.versionCode, mVersionCode));
+            return false;
+        }
+        if (!signaturesMatch(mSigHashes, target)) {
+            Slog.w(TAG, "Package signature mismtach");
+            return false;
+        }
+        return true;
+    }
+
+    public static ShortcutPackageInfo generateForInstalledPackage(
+            ShortcutService s, String packageName, @UserIdInt int userId) {
+        final PackageInfo pi = s.getPackageInfo(packageName, userId, /*signature=*/ true);
+        if (pi.signatures == null || pi.signatures.length == 0) {
+            Slog.e(TAG, "Can't get signatures: package=" + packageName);
+            return null;
+        }
+        final ShortcutPackageInfo ret = new ShortcutPackageInfo(packageName, pi.versionCode,
+                hashSignatureArray(pi.signatures), /* shadow=*/ false);
+
+        return ret;
+    }
+
+    public void refreshAndSave(ShortcutService s, @UserIdInt int userId) {
+        final PackageInfo pi = s.getPackageInfo(mPackageName, userId, /*getSignatures=*/ true);
+        if (pi == null) {
+            Slog.w(TAG, "Package not found: " + mPackageName);
+            return;
+        }
+        mVersionCode = pi.versionCode;
+        mSigHashes = hashSignatureArray(pi.signatures);
+
+        s.scheduleSaveUser(userId);
+    }
+
+    public void saveToXml(XmlSerializer out, boolean forBackup)
+            throws IOException, XmlPullParserException {
+
+        out.startTag(null, TAG_ROOT);
+
+        ShortcutService.writeAttr(out, ATTR_NAME, mPackageName);
+        ShortcutService.writeAttr(out, ATTR_VERSION, mVersionCode);
+        ShortcutService.writeAttr(out, ATTR_SHADOW, mIsShadow);
+
+        for (int i = 0; i < mSigHashes.size(); i++) {
+            out.startTag(null, TAG_SIGNATURE);
+            ShortcutService.writeAttr(out, ATTR_SIGNATURE_HASH, Base64.encode(mSigHashes.get(i)));
+            out.endTag(null, TAG_SIGNATURE);
+        }
+        out.endTag(null, TAG_ROOT);
+    }
+
+    public static ShortcutPackageInfo loadFromXml(XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+
+        final String packageName = ShortcutService.parseStringAttribute(parser, ATTR_NAME);
+        final int versionCode = ShortcutService.parseIntAttribute(parser, ATTR_VERSION);
+        final boolean shadow = ShortcutService.parseBooleanAttribute(parser, ATTR_SHADOW);
+
+        final ArrayList<byte[]> hashes = new ArrayList<>();
+
+
+        final int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type != XmlPullParser.START_TAG) {
+                continue;
+            }
+            final int depth = parser.getDepth();
+            final String tag = parser.getName();
+            switch (tag) {
+                case TAG_SIGNATURE: {
+                    final String hash = ShortcutService.parseStringAttribute(
+                            parser, ATTR_SIGNATURE_HASH);
+                    hashes.add(Base64.decode(hash.getBytes()));
+                    continue;
+                }
+            }
+            throw ShortcutService.throwForInvalidTag(depth, tag);
+        }
+        return new ShortcutPackageInfo(packageName, versionCode, hashes, shadow);
+    }
+
+    public void dump(ShortcutService s, PrintWriter pw, String prefix) {
+        pw.println();
+
+        pw.print(prefix);
+        pw.print("PackageInfo: ");
+        pw.print(mPackageName);
+        pw.println();
+
+        pw.print(prefix);
+        pw.print("  IsShadow: ");
+        pw.print(mIsShadow);
+        pw.println();
+
+        pw.print(prefix);
+        pw.print("  Version: ");
+        pw.print(mVersionCode);
+        pw.println();
+
+        for (int i = 0; i < mSigHashes.size(); i++) {
+            pw.print(prefix);
+            pw.print("    ");
+            pw.print("SigHash: ");
+            pw.println(HexEncoding.encode(mSigHashes.get(i)));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
similarity index 61%
copy from packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
copy to services/core/java/com/android/server/pm/ShortcutPackageItem.java
index aaf77af..526c84d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ToggleHistoryEvent.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -13,16 +13,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.server.pm;
 
-package com.android.systemui.recents.events.activity;
+import android.annotation.NonNull;
 
-import com.android.systemui.recents.events.EventBus;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
-/**
- * This is sent when the history view button is clicked.
- */
-public class ToggleHistoryEvent extends EventBus.AnimatedEvent {
+import java.io.IOException;
 
-    // Simple event
+public interface ShortcutPackageItem {
+    @NonNull
+    String getPackageName();
 
+    void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
+            throws IOException, XmlPullParserException;
 }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 42954f5..0b33ada 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -19,13 +19,17 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.ContentProvider;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.IShortcutService;
 import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
@@ -55,7 +59,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
-import android.text.format.Formatter;
 import android.text.format.Time;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -70,13 +73,13 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
 import libcore.io.IoUtils;
-import libcore.util.Objects;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -122,6 +125,7 @@
 
     static final boolean DEBUG = false; // STOPSHIP if true
     static final boolean DEBUG_LOAD = false; // STOPSHIP if true
+    static final boolean ENABLE_DEBUG_COMMAND = true; // STOPSHIP if true
 
     @VisibleForTesting
     static final long DEFAULT_RESET_INTERVAL_SEC = 24 * 60 * 60; // 1 day
@@ -249,6 +253,7 @@
 
     private int mSaveDelayMillis;
 
+    private final IPackageManager mIPackageManager;
     private final PackageManagerInternal mPackageManagerInternal;
     private final UserManager mUserManager;
 
@@ -264,6 +269,7 @@
         mContext = Preconditions.checkNotNull(context);
         LocalServices.addService(ShortcutServiceInternal.class, new LocalService());
         mHandler = new Handler(looper);
+        mIPackageManager = AppGlobals.getPackageManager();
         mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mUserManager = context.getSystemService(UserManager.class);
 
@@ -319,6 +325,8 @@
         synchronized (mLock) {
             // Preload
             getUserShortcutsLocked(userId);
+
+            cleanupGonePackages(userId);
         }
     }
 
@@ -434,6 +442,10 @@
         return parser.getAttributeValue(null, attribute);
     }
 
+    static boolean parseBooleanAttribute(XmlPullParser parser, String attribute) {
+        return parseLongAttribute(parser, attribute) == 1;
+    }
+
     static int parseIntAttribute(XmlPullParser parser, String attribute) {
         return (int) parseLongAttribute(parser, attribute);
     }
@@ -510,6 +522,12 @@
         writeAttr(out, name, String.valueOf(value));
     }
 
+    static void writeAttr(XmlSerializer out, String name, boolean value) throws IOException {
+        if (value) {
+            writeAttr(out, name, "1");
+        }
+    }
+
     static void writeAttr(XmlSerializer out, String name, ComponentName comp) throws IOException {
         if (comp == null) return;
         writeAttr(out, name, comp.flattenToString());
@@ -616,7 +634,7 @@
             out.setOutput(outs, StandardCharsets.UTF_8.name());
             out.startDocument(null, true);
 
-            getUserShortcutsLocked(userId).saveToXml(out);
+            getUserShortcutsLocked(userId).saveToXml(this, out, /* forBackup= */ false);
 
             out.endDocument();
 
@@ -682,17 +700,17 @@
     }
 
     private void scheduleSaveBaseState() {
-        scheduleSave(UserHandle.USER_NULL); // Special case -- use USER_NULL for base state.
+        scheduleSaveInner(UserHandle.USER_NULL); // Special case -- use USER_NULL for base state.
     }
 
     void scheduleSaveUser(@UserIdInt int userId) {
-        scheduleSave(userId);
+        scheduleSaveInner(userId);
     }
 
     // In order to re-schedule, we need to reuse the same instance, so keep it in final.
     private final Runnable mSaveDirtyInfoRunner = this::saveDirtyInfo;
 
-    private void scheduleSave(@UserIdInt int userId) {
+    private void scheduleSaveInner(@UserIdInt int userId) {
         if (DEBUG) {
             Slog.d(TAG, "Scheduling to save for " + userId);
         }
@@ -1169,6 +1187,8 @@
         final int size = newShortcuts.size();
 
         synchronized (mLock) {
+            getUserShortcutsLocked(userId).ensurePackageInfo(this, packageName, userId);
+
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
 
             // Throttling.
@@ -1204,6 +1224,8 @@
         final int size = newShortcuts.size();
 
         synchronized (mLock) {
+            getUserShortcutsLocked(userId).ensurePackageInfo(this, packageName, userId);
+
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
 
             // Throttling.
@@ -1241,6 +1263,8 @@
         verifyCaller(packageName, userId);
 
         synchronized (mLock) {
+            getUserShortcutsLocked(userId).ensurePackageInfo(this, packageName, userId);
+
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
 
             // Throttling.
@@ -1376,10 +1400,7 @@
     @VisibleForTesting
     boolean hasShortcutHostPermissionInner(@NonNull String callingPackage, int userId) {
         synchronized (mLock) {
-            long start = 0;
-            if (DEBUG) {
-                start = System.currentTimeMillis();
-            }
+            long start = System.currentTimeMillis();
 
             final ShortcutUser user = getUserShortcutsLocked(userId);
 
@@ -1430,8 +1451,8 @@
                     lastPriority = ri.priority;
                 }
             }
+            final long end = System.currentTimeMillis();
             if (DEBUG) {
-                long end = System.currentTimeMillis();
                 Slog.v(TAG, String.format("hasShortcutPermission took %d ms", end - start));
             }
             if (detected != null) {
@@ -1473,6 +1494,9 @@
             mUser.getPackages().valueAt(i).refreshPinnedFlags(this);
         }
 
+        // Remove the package info too.
+        mUser.getPackageInfos().remove(packageName);
+
         scheduleSaveUser(userId);
 
         if (doNotify) {
@@ -1567,6 +1591,9 @@
             Preconditions.checkNotNull(shortcutIds, "shortcutIds");
 
             synchronized (mLock) {
+                getUserShortcutsLocked(userId).ensurePackageInfo(
+                        ShortcutService.this, callingPackage, userId);
+
                 getLauncherShortcuts(callingPackage, userId).pinShortcuts(
                         ShortcutService.this, packageName, shortcutIds);
             }
@@ -1640,7 +1667,16 @@
         }
     }
 
-    private PackageMonitor mPackageMonitor = new PackageMonitor() {
+    /**
+     * Package event callbacks.
+     */
+    @VisibleForTesting
+    final PackageMonitor mPackageMonitor = new PackageMonitor() {
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+            handlePackageAdded(packageName, getChangingUserId());
+        }
+
         @Override
         public void onPackageUpdateFinished(String packageName, int uid) {
             handlePackageUpdateFinished(packageName, getChangingUserId());
@@ -1650,38 +1686,120 @@
         public void onPackageRemoved(String packageName, int uid) {
             handlePackageRemoved(packageName, getChangingUserId());
         }
-
-        @Override
-        public void onPackageRemovedAllUsers(String packageName, int uid) {
-            handlePackageRemovedAllUsers(packageName, getChangingUserId());
-        }
     };
 
-    void handlePackageUpdateFinished(String packageName, @UserIdInt int userId) {
+    /**
+     * Called when a user is unlocked.  Check all known packages still exist, and otherwise
+     * perform cleanup.
+     */
+    private void cleanupGonePackages(@UserIdInt int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "onPackageUpdateFinished() userId=" + userId);
+            Slog.d(TAG, "cleanupGonePackages() userId=" + userId);
         }
-        // TODO Update the version.
+        ArrayList<String> gonePackages = null;
+
+        final ShortcutUser user = getUserShortcutsLocked(userId);
+        final ArrayMap<String, ShortcutPackageInfo> infos = user.getPackageInfos();
+        for (int i = infos.size() -1; i >= 0; i--) {
+            final ShortcutPackageInfo info = infos.valueAt(i);
+            if (info.isShadow()) {
+                continue;
+            }
+            if (isPackageInstalled(info.getPackageName(), userId)) {
+                continue;
+            }
+            gonePackages = ArrayUtils.add(gonePackages, info.getPackageName());
+        }
+        if (gonePackages != null) {
+            for (int i = gonePackages.size() - 1; i >= 0; i--) {
+                handlePackageGone(gonePackages.get(i), userId);
+            }
+        }
     }
 
-    void handlePackageRemoved(String packageName, @UserIdInt int userId) {
+    private void handlePackageAdded(String packageName, @UserIdInt int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "onPackageRemoved() userId=" + userId);
+            Slog.d(TAG, String.format("handlePackageAdded: %s user=%d", packageName, userId));
+        }
+        synchronized (mLock) {
+            final ArrayMap<String, ShortcutPackageInfo> infos =
+                    getUserShortcutsLocked(userId).getPackageInfos();
+            final ShortcutPackageInfo existing = infos.get(packageName);
+
+            if (existing != null && existing.isShadow()) {
+                Slog.w(TAG, "handlePackageAdded: TODO Restore not implemented");
+            }
+        }
+    }
+
+    private void handlePackageUpdateFinished(String packageName, @UserIdInt int userId) {
+        final PackageInfo pi = getPackageInfo(packageName, userId);
+        if (pi == null) {
+            Slog.w(TAG, "Package not found: " + packageName);
+            return;
+        }
+        synchronized (mLock) {
+            final ShortcutPackageInfo spi =
+                    getUserShortcutsLocked(userId).getPackageInfos().get(packageName);
+            if (spi != null) {
+                spi.refreshAndSave(this, userId);
+            }
+        }
+    }
+
+    private void handlePackageRemoved(String packageName, @UserIdInt int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, String.format("handlePackageRemoved: %s user=%d", packageName, userId));
         }
         synchronized (mLock) {
             cleanUpPackageLocked(packageName, userId);
         }
     }
 
-    void handlePackageRemovedAllUsers(String packageName, @UserIdInt int userId) {
+    private void handlePackageGone(String packageName, @UserIdInt int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "onPackageRemovedAllUsers() userId=" + userId);
+            Slog.d(TAG, String.format("handlePackageGone: %s user=%d", packageName, userId));
         }
         synchronized (mLock) {
             cleanUpPackageLocked(packageName, userId);
         }
+    }
 
-        // TODO Remove from all users, which we can't if the user is locked.
+    // === Backup & restore ===
+
+    PackageInfo getPackageInfo(String packageName, @UserIdInt int userId) {
+        return getPackageInfo(packageName, userId, /*getSignatures=*/ false);
+    }
+
+    PackageInfo getPackageInfo(String packageName, @UserIdInt int userId,
+            boolean getSignatures) {
+        return injectPackageInfo(packageName, userId, getSignatures);
+    }
+
+    @VisibleForTesting
+    PackageInfo injectPackageInfo(String packageName, @UserIdInt int userId,
+            boolean getSignatures) {
+        try {
+            return mIPackageManager.getPackageInfo(packageName,
+                    PackageManager.MATCH_DIRECT_BOOT_AWARE
+                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+                    | (getSignatures ? PackageManager.GET_SIGNATURES : 0)
+                    , userId);
+        } catch (RemoteException e) {
+            // Shouldn't happen.
+            Slog.wtf(TAG, "RemoteException", e);
+            return null;
+        }
+    }
+
+    boolean shouldBackupApp(String packageName, int userId) {
+        final PackageInfo pi = getPackageInfo(packageName, userId);
+        return (pi != null) &&
+                ((pi.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
+    }
+
+    private boolean isPackageInstalled(String packageName, int userId) {
+        return getPackageInfo(packageName, userId) != null;
     }
 
     // === Dump ===
@@ -2039,4 +2157,14 @@
             return pkg.findShortcutById(shortcutId);
         }
     }
+
+    @VisibleForTesting
+    ShortcutPackageInfo getPackageInfoForTest(String packageName, int userId) {
+        synchronized (mLock) {
+            final ShortcutUser user = mUsers.get(userId);
+            if (user == null) return null;
+
+            return user.getPackageInfos().get(packageName);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 4a6b1e4..1a00cda 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -19,6 +19,7 @@
 import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.util.ArrayMap;
+import android.util.Slog;
 
 import libcore.util.Objects;
 
@@ -47,6 +48,8 @@
 
     private final ArrayMap<String, ShortcutLauncher> mLaunchers = new ArrayMap<>();
 
+    private final ArrayMap<String, ShortcutPackageInfo> mPackageInfos = new ArrayMap<>();
+
     private ComponentName mLauncherComponent;
 
     public ShortcutUser(int userId) {
@@ -61,6 +64,10 @@
         return mLaunchers;
     }
 
+    public ArrayMap<String, ShortcutPackageInfo> getPackageInfos() {
+        return mPackageInfos;
+    }
+
     public ShortcutPackage getPackageShortcuts(@NonNull String packageName) {
         ShortcutPackage ret = mPackages.get(packageName);
         if (ret == null) {
@@ -79,25 +86,58 @@
         return ret;
     }
 
-    public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
+    public void ensurePackageInfo(ShortcutService s, String packageName, @UserIdInt int userId) {
+        final ShortcutPackageInfo existing = mPackageInfos.get(packageName);
+
+        if (existing != null) {
+            return;
+        }
+        if (ShortcutService.DEBUG) {
+            Slog.d(TAG, String.format("Fetching package info: %s user=%d", packageName, userId));
+        }
+        final ShortcutPackageInfo newSpi = ShortcutPackageInfo.generateForInstalledPackage(
+                s, packageName, userId);
+        mPackageInfos.put(packageName, newSpi);
+        s.scheduleSaveUser(mUserId);
+    }
+
+    public void saveToXml(ShortcutService s, XmlSerializer out, boolean forBackup)
+            throws IOException, XmlPullParserException {
         out.startTag(null, TAG_ROOT);
 
         ShortcutService.writeTagValue(out, TAG_LAUNCHER,
                 mLauncherComponent);
 
-        final int lsize = mLaunchers.size();
-        for (int i = 0; i < lsize; i++) {
-            mLaunchers.valueAt(i).saveToXml(out);
+        {
+            final int size = mPackageInfos.size();
+            for (int i = 0; i < size; i++) {
+                saveShortcutPackageItem(s, out, mPackageInfos.valueAt(i), forBackup);
+            }
         }
-
-        final int psize = mPackages.size();
-        for (int i = 0; i < psize; i++) {
-            mPackages.valueAt(i).saveToXml(out);
+        {
+            final int size = mLaunchers.size();
+            for (int i = 0; i < size; i++) {
+                saveShortcutPackageItem(s, out, mLaunchers.valueAt(i), forBackup);
+            }
+        }
+        {
+            final int size = mPackages.size();
+            for (int i = 0; i < size; i++) {
+                saveShortcutPackageItem(s, out, mPackages.valueAt(i), forBackup);
+            }
         }
 
         out.endTag(null, TAG_ROOT);
     }
 
+    private void saveShortcutPackageItem(ShortcutService s, XmlSerializer out,
+            ShortcutPackageItem spi, boolean forBackup) throws IOException, XmlPullParserException {
+        if (forBackup && !s.shouldBackupApp(spi.getPackageName(), mUserId)) {
+            return; // Don't save.
+        }
+        spi.saveToXml(out, forBackup);
+    }
+
     public static ShortcutUser loadFromXml(XmlPullParser parser, int userId)
             throws IOException, XmlPullParserException {
         final ShortcutUser ret = new ShortcutUser(userId);
@@ -121,7 +161,7 @@
                     final ShortcutPackage shortcuts = ShortcutPackage.loadFromXml(parser, userId);
 
                     // Don't use addShortcut(), we don't need to save the icon.
-                    ret.getPackages().put(shortcuts.mPackageName, shortcuts);
+                    ret.getPackages().put(shortcuts.getPackageName(), shortcuts);
                     continue;
                 }
 
@@ -129,7 +169,15 @@
                     final ShortcutLauncher shortcuts =
                             ShortcutLauncher.loadFromXml(parser, userId);
 
-                    ret.getLaunchers().put(shortcuts.mPackageName, shortcuts);
+                    ret.getLaunchers().put(shortcuts.getPackageName(), shortcuts);
+                    continue;
+                }
+
+                case ShortcutPackageInfo.TAG_ROOT: {
+                    final ShortcutPackageInfo pi =
+                            ShortcutPackageInfo.loadFromXml(parser);
+
+                    ret.getPackageInfos().put(pi.getPackageName(), pi);
                     continue;
                 }
             }
@@ -175,5 +223,9 @@
         for (int i = 0; i < mPackages.size(); i++) {
             mPackages.valueAt(i).dump(s, pw, prefix + "  ");
         }
+
+        for (int i = 0; i < mPackageInfos.size(); i++) {
+            mPackageInfos.valueAt(i).dump(s, pw, prefix + "  ");
+        }
     }
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 715f1e5..5263c37 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -20,6 +20,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
@@ -37,6 +38,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Environment;
@@ -122,6 +124,7 @@
     private static final String ATTR_ID = "id";
     private static final String ATTR_CREATION_TIME = "created";
     private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
+    private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint";
     private static final String ATTR_SERIAL_NO = "serialNumber";
     private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
     private static final String ATTR_PARTIAL = "partial";
@@ -380,8 +383,6 @@
             removeUserState(ui.id);
         }
 
-        onUserForeground(UserHandle.USER_SYSTEM);
-
         mAppOpsService = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
 
@@ -458,7 +459,7 @@
                     continue;
                 }
                 if (!excludeDying || !mRemovingUserIds.get(ui.id)) {
-                    users.add(ui);
+                    users.add(userWithName(ui));
                 }
             }
             return users;
@@ -500,7 +501,7 @@
             if (mRemovingUserIds.get(profile.id)) {
                 continue;
             }
-            users.add(profile);
+            users.add(userWithName(profile));
         }
         return users;
     }
@@ -653,7 +654,21 @@
     public UserInfo getUserInfo(int userId) {
         checkManageUsersPermission("query user");
         synchronized (mUsersLock) {
-            return getUserInfoLU(userId);
+            return userWithName(getUserInfoLU(userId));
+        }
+    }
+
+    /**
+     * Returns a UserInfo object with the name filled in, for Owner, or the original
+     * if the name is already set.
+     */
+    private UserInfo userWithName(UserInfo orig) {
+        if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) {
+            UserInfo withName = new UserInfo(orig);
+            withName.name = getOwnerName();
+            return withName;
+        } else {
+            return orig;
         }
     }
 
@@ -1459,9 +1474,7 @@
             flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY;
         }
         // Create the system user
-        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM,
-                mContext.getResources().getString(com.android.internal.R.string.owner_name), null,
-                flags);
+        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags);
         UserData userData = new UserData();
         userData.info = system;
         synchronized (mUsersLock) {
@@ -1482,6 +1495,10 @@
         writeUserLP(userData);
     }
 
+    private String getOwnerName() {
+        return mContext.getResources().getString(com.android.internal.R.string.owner_name);
+    }
+
     private void scheduleWriteUser(UserData UserData) {
         if (DBG) {
             debug("scheduleWriteUser");
@@ -1525,6 +1542,8 @@
             serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime));
             serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME,
                     Long.toString(userInfo.lastLoggedInTime));
+            serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT,
+                    userInfo.lastLoggedInFingerprint);
             if (userInfo.iconPath != null) {
                 serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
             }
@@ -1551,9 +1570,11 @@
                     serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType);
                 }
             }
-            serializer.startTag(null, TAG_NAME);
-            serializer.text(userInfo.name);
-            serializer.endTag(null, TAG_NAME);
+            if (userInfo.name != null) {
+                serializer.startTag(null, TAG_NAME);
+                serializer.text(userInfo.name);
+                serializer.endTag(null, TAG_NAME);
+            }
             synchronized (mRestrictionsLock) {
                 UserRestrictionsUtils.writeRestrictions(serializer,
                         mBaseUserRestrictions.get(userInfo.id), TAG_RESTRICTIONS);
@@ -1653,6 +1674,7 @@
         String iconPath = null;
         long creationTime = 0L;
         long lastLoggedInTime = 0L;
+        String lastLoggedInFingerprint = null;
         int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
         int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
         boolean partial = false;
@@ -1693,6 +1715,8 @@
                 iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
                 creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
                 lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
+                lastLoggedInFingerprint = parser.getAttributeValue(null,
+                        ATTR_LAST_LOGGED_IN_FINGERPRINT);
                 profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID,
                         UserInfo.NO_PROFILE_GROUP_ID);
                 restrictedProfileParentId = readIntAttribute(parser,
@@ -1745,6 +1769,7 @@
             userInfo.serialNumber = serialNumber;
             userInfo.creationTime = creationTime;
             userInfo.lastLoggedInTime = lastLoggedInTime;
+            userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint;
             userInfo.partial = partial;
             userInfo.guestToRemove = guestToRemove;
             userInfo.profileGroupId = profileGroupId;
@@ -2535,7 +2560,7 @@
      * Called right before a user is unlocked. This gives us a chance to prepare
      * app storage.
      */
-    public void onBeforeUnlockUser(int userId) {
+    public void onBeforeUnlockUser(@UserIdInt int userId) {
         final int userSerial = getUserSerialNumber(userId);
         prepareUserStorage(userId, userSerial, StorageManager.FLAG_STORAGE_CE);
         mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE);
@@ -2545,17 +2570,19 @@
      * Make a note of the last started time of a user and do some cleanup.
      * @param userId the user that was just foregrounded
      */
-    public void onUserForeground(int userId) {
+    public void onUserLoggedIn(@UserIdInt int userId) {
         UserData userData = getUserDataNoChecks(userId);
         if (userData == null || userData.info.partial) {
             Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
             return;
         }
-        long now = System.currentTimeMillis();
+
+        final long now = System.currentTimeMillis();
         if (now > EPOCH_PLUS_30_YEARS) {
             userData.info.lastLoggedInTime = now;
-            scheduleWriteUser(userData);
         }
+        userData.info.lastLoggedInFingerprint = Build.FINGERPRINT;
+        scheduleWriteUser(userData);
     }
 
     /**
@@ -2820,6 +2847,8 @@
                         sb.append(" ago");
                         pw.println(sb);
                     }
+                    pw.print("    Last logged in fingerprint: ");
+                    pw.println(userInfo.lastLoggedInFingerprint);
                     pw.print("    Has profile owner: ");
                     pw.println(mIsUserManaged.get(userId));
                     pw.println("    Restrictions:");
diff --git a/services/core/java/com/android/server/policy/EnableAccessibilityController.java b/services/core/java/com/android/server/policy/EnableAccessibilityController.java
index da9c001..6b203a9 100644
--- a/services/core/java/com/android/server/policy/EnableAccessibilityController.java
+++ b/services/core/java/com/android/server/policy/EnableAccessibilityController.java
@@ -16,7 +16,9 @@
 
 package com.android.server.policy;
 
+import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -32,19 +34,25 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.speech.tts.TextToSpeech;
+import android.util.Log;
 import android.util.MathUtils;
 import android.view.IWindowManager;
 import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.WindowManagerInternal;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.IAccessibilityManager;
 
 import com.android.internal.R;
+import com.android.server.LocalServices;
 
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
 public class EnableAccessibilityController {
+    private static final String TAG = "EnableAccessibilityController";
 
     private static final int SPEAK_WARNING_DELAY_MILLIS = 2000;
     private static final int ENABLE_ACCESSIBILITY_DELAY_MILLIS = 6000;
@@ -75,9 +83,6 @@
         }
     };
 
-    private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
-            ServiceManager.getService("window"));
-
     private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager
             .Stub.asInterface(ServiceManager.getService("accessibility"));
 
@@ -132,7 +137,7 @@
                 && !getInstalledSpeakingAccessibilityServices(context).isEmpty();
     }
 
-    private static List<AccessibilityServiceInfo> getInstalledSpeakingAccessibilityServices(
+    public static List<AccessibilityServiceInfo> getInstalledSpeakingAccessibilityServices(
             Context context) {
         List<AccessibilityServiceInfo> services = new ArrayList<AccessibilityServiceInfo>();
         services.addAll(AccessibilityManager.getInstance(context)
@@ -213,71 +218,74 @@
     }
 
     private void enableAccessibility() {
-        List<AccessibilityServiceInfo> services = getInstalledSpeakingAccessibilityServices(
-                mContext);
-        if (services.isEmpty()) {
+        if (enableAccessibility(mContext)) {
+            mOnAccessibilityEnabledCallback.run();
+        }
+    }
+
+    public static boolean enableAccessibility(Context context) {
+        final IAccessibilityManager accessibilityManager = IAccessibilityManager
+                .Stub.asInterface(ServiceManager.getService("accessibility"));
+        final WindowManagerInternal windowManager = LocalServices.getService(
+                WindowManagerInternal.class);
+        final UserManager userManager = (UserManager) context.getSystemService(
+                Context.USER_SERVICE);
+        ComponentName componentName = getInstalledSpeakingAccessibilityServiceComponent(context);
+        if (componentName == null) {
+            return false;
+        }
+
+        boolean keyguardLocked = windowManager.isKeyguardLocked();
+        final boolean hasMoreThanOneUser = userManager.getUsers().size() > 1;
+        try {
+            if (!keyguardLocked || !hasMoreThanOneUser) {
+                final int userId = ActivityManager.getCurrentUser();
+                accessibilityManager.enableAccessibilityService(componentName, userId);
+            } else if (keyguardLocked) {
+                accessibilityManager.temporaryEnableAccessibilityStateUntilKeyguardRemoved(
+                        componentName, true /* enableTouchExploration */);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "cannot enable accessibilty: " + e);
+        }
+
+        return true;
+    }
+
+    public static void disableAccessibility(Context context) {
+        final IAccessibilityManager accessibilityManager = IAccessibilityManager
+                .Stub.asInterface(ServiceManager.getService("accessibility"));
+        ComponentName componentName = getInstalledSpeakingAccessibilityServiceComponent(context);
+        if (componentName == null) {
             return;
         }
-        boolean keyguardLocked = false;
+
+        final int userId = ActivityManager.getCurrentUser();
         try {
-            keyguardLocked = mWindowManager.isKeyguardLocked();
-        } catch (RemoteException re) {
-            /* ignore */
+            accessibilityManager.disableAccessibilityService(componentName, userId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "cannot disable accessibility " + e);
+        }
+    }
+
+    public static boolean isAccessibilityEnabled(Context context) {
+        final AccessibilityManager accessibilityManager =
+                context.getSystemService(AccessibilityManager.class);
+        List enabledServices = accessibilityManager.getEnabledAccessibilityServiceList(
+                AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+        return enabledServices != null && !enabledServices.isEmpty();
+    }
+
+    @Nullable
+    public static ComponentName getInstalledSpeakingAccessibilityServiceComponent(
+            Context context) {
+        List<AccessibilityServiceInfo> services =
+                getInstalledSpeakingAccessibilityServices(context);
+        if (services.isEmpty()) {
+            return null;
         }
 
-        final boolean hasMoreThanOneUser = mUserManager.getUsers().size() > 1;
-
-        AccessibilityServiceInfo service = services.get(0);
-        boolean enableTouchExploration = (service.flags
-                & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
-        // Try to find a service supporting explore by touch.
-        if (!enableTouchExploration) {
-            final int serviceCount = services.size();
-            for (int i = 1; i < serviceCount; i++) {
-                AccessibilityServiceInfo candidate = services.get(i);
-                if ((candidate.flags & AccessibilityServiceInfo
-                        .FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0) {
-                    enableTouchExploration = true;
-                    service = candidate;
-                    break;
-                }
-            }
-        }
-
-        ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
-        ComponentName componentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
-        if (!keyguardLocked || !hasMoreThanOneUser) {
-            final int userId = ActivityManager.getCurrentUser();
-            String enabledServiceString = componentName.flattenToString();
-            ContentResolver resolver = mContext.getContentResolver();
-            // Enable one speaking accessibility service.
-            Settings.Secure.putStringForUser(resolver,
-                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                    enabledServiceString, userId);
-            // Allow the services we just enabled to toggle touch exploration.
-            Settings.Secure.putStringForUser(resolver,
-                    Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
-                    enabledServiceString, userId);
-            // Enable touch exploration.
-            if (enableTouchExploration) {
-                Settings.Secure.putIntForUser(resolver, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
-                        1, userId);
-            }
-            // Enable accessibility script injection (AndroidVox) for web content.
-            Settings.Secure.putIntForUser(resolver, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
-                    1, userId);
-            // Turn on accessibility mode last.
-            Settings.Secure.putIntForUser(resolver, Settings.Secure.ACCESSIBILITY_ENABLED,
-                    1, userId);
-        } else if (keyguardLocked) {
-            try {
-                mAccessibilityManager.temporaryEnableAccessibilityStateUntilKeyguardRemoved(
-                        componentName, enableTouchExploration);
-            } catch (RemoteException re) {
-                /* ignore */
-            }
-        }
-
-        mOnAccessibilityEnabledCallback.run();
+        ServiceInfo serviceInfo = services.get(0).getResolveInfo().serviceInfo;
+        return new ComponentName(serviceInfo.packageName, serviceInfo.name);
     }
 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0115a08..1645366 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2778,8 +2778,10 @@
 
         // If the divider is behind the navigation bar, don't animate.
         if (mNavigationBar != null
-                && (win.getFrameLw().top + insets >= mNavigationBar.getFrameLw().top
-                        || win.getFrameLw().left + insets >= mNavigationBar.getFrameLw().left)) {
+                && ((mNavigationBarOnBottom
+                        && win.getFrameLw().top + insets >= mNavigationBar.getFrameLw().top)
+                || (!mNavigationBarOnBottom
+                        && win.getFrameLw().left + insets >= mNavigationBar.getFrameLw().left))) {
             return 0;
         }
         if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
@@ -3101,7 +3103,7 @@
         } else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) {
             if (down) {
                 if (repeatCount == 0) {
-                    toggleKeyboardShortcutsMenu();
+                    toggleKeyboardShortcutsMenu(event.getDeviceId());
                 }
             }
         } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
@@ -3576,11 +3578,11 @@
         }
     }
 
-    private void toggleKeyboardShortcutsMenu() {
+    private void toggleKeyboardShortcutsMenu(int deviceId) {
         try {
             IStatusBarService statusbar = getStatusBarService();
             if (statusbar != null) {
-                statusbar.toggleKeyboardShortcutsMenu();
+                statusbar.toggleKeyboardShortcutsMenu(deviceId);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException when showing keyboard shortcuts menu", e);
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index 9d353c6..86d0468 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -29,6 +29,8 @@
 import android.view.animation.TranslateAnimation;
 
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
 
 import static android.view.WindowManagerInternal.*;
 
@@ -103,6 +105,20 @@
                 }
             });
         }
+
+        @Override
+        public void onAppTransitionFinishedLocked(IBinder token) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    StatusBarManagerInternal statusbar = LocalServices.getService(
+                            StatusBarManagerInternal.class);
+                    if (statusbar != null) {
+                        statusbar.appTransitionFinished();
+                    }
+                }
+            });
+        }
     };
 
     public StatusBarController() {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 6bda4ed..9614417 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -34,4 +34,5 @@
     void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
             Rect fullscreenBounds, Rect dockedBounds, String cause);
     void toggleSplitScreen();
+    void appTransitionFinished();
 }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index d24e1af..4a00ebd 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -214,6 +214,15 @@
                 } catch (RemoteException ex) {}
             }
         }
+
+        public void appTransitionFinished() {
+            enforceStatusBarService();
+            if (mBar != null) {
+                try {
+                    mBar.appTransitionFinished();
+                } catch (RemoteException ex) {}
+            }
+        }
     };
 
     // ================================================================================
@@ -564,10 +573,10 @@
     }
 
     @Override
-    public void toggleKeyboardShortcutsMenu() {
+    public void toggleKeyboardShortcutsMenu(int deviceId) {
         if (mBar != null) {
             try {
-                mBar.toggleKeyboardShortcutsMenu();
+                mBar.toggleKeyboardShortcutsMenu(deviceId);
             } catch (RemoteException ex) {}
         }
     }
diff --git a/services/core/java/com/android/server/utils/ManagedApplicationService.java b/services/core/java/com/android/server/utils/ManagedApplicationService.java
index ad8acef0..0f251fd 100644
--- a/services/core/java/com/android/server/utils/ManagedApplicationService.java
+++ b/services/core/java/com/android/server/utils/ManagedApplicationService.java
@@ -62,8 +62,6 @@
     private IInterface mBoundInterface;
     private PendingEvent mPendingEvent;
 
-
-
     private ManagedApplicationService(final Context context, final ComponentName component,
             final int userId, int clientLabel, String settingsAction,
             BinderChecker binderChecker) {
@@ -211,6 +209,7 @@
                         } else {
                             // Service connection wasn't pending, must have been disconnected
                             mContext.unbindService(this);
+                            return;
                         }
 
                         try {
@@ -242,6 +241,8 @@
                 @Override
                 public void onServiceDisconnected(ComponentName componentName) {
                     Slog.w(TAG, "Service disconnected: " + intent);
+                    mConnection = null;
+                    mBoundInterface = null;
                 }
             };
 
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 8316efa..93bb9d7 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -38,6 +38,17 @@
     public abstract boolean isInVrMode();
 
     /**
+     * Return {@code true} if the given package is the currently bound VrListenerService for the
+     * given user.
+     *
+     * @param packageName The package name to check.
+     * @param userId the user ID to check the package name for.
+     *
+     * @return {@code true} if the given package is the currently bound VrListenerService.
+     */
+    public abstract boolean isCurrentVrListener(String packageName, int userId);
+
+    /**
      * Set the current VR mode state.
      *
      * @param enabled {@code true} to enable VR mode.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 6bf949c..aa6f59e 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -127,6 +127,11 @@
         }
 
         @Override
+        public boolean isCurrentVrListener(String packageName, int userId) {
+            return VrManagerService.this.isCurrentVrListener(packageName, userId);
+        }
+
+        @Override
         public void registerListener(VrStateListener listener) {
             VrManagerService.this.addListener(listener);
         }
@@ -355,6 +360,16 @@
         }
     }
 
+    private boolean isCurrentVrListener(String packageName, int userId) {
+        synchronized (mLock) {
+            if (mCurrentVrService == null) {
+                return false;
+            }
+            return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
+                    userId == mCurrentVrService.getUserId();
+        }
+    }
+
     private void addListener(VrStateListener listener) {
         synchronized (mLock) {
             mListeners.add(listener);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index fb9b1ce..4848523 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1262,6 +1262,7 @@
         return null;
     }
 
+    @Override
     public void setWallpaperComponentChecked(ComponentName name, String callingPackage) {
         if (isWallpaperSupported(callingPackage) && isWallpaperSettingAllowed(callingPackage)) {
             setWallpaperComponent(name);
@@ -1269,6 +1270,7 @@
     }
 
     // ToDo: Remove this version of the function
+    @Override
     public void setWallpaperComponent(ComponentName name) {
         checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
         synchronized (mLock) {
@@ -1281,7 +1283,9 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 wallpaper.imageWallpaperPending = false;
-                bindWallpaperComponentLocked(name, false, true, wallpaper, null);
+                if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
+                    wallpaper.wallpaperId = makeWallpaperIdLocked();
+                }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 5cb7099..d684278 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -43,10 +43,14 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Path;
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.IBinder;
@@ -73,6 +77,7 @@
 import com.android.server.wm.WindowManagerService.H;
 import com.android.server.wm.animation.ClipRectLRAnimation;
 import com.android.server.wm.animation.ClipRectTBAnimation;
+import com.android.server.wm.animation.CurvedTranslateAnimation;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -127,6 +132,8 @@
     public static final int TRANSIT_TASK_IN_PLACE = 17;
     /** An activity is being relaunched (e.g. due to configuration change). */
     public static final int TRANSIT_ACTIVITY_RELAUNCH = 18;
+    /** A task is being docked from recents. */
+    public static final int TRANSIT_DOCK_TASK_FROM_RECENTS = 19;
 
     /** Fraction of animation at which the recents thumbnail stays completely transparent */
     private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.5f;
@@ -139,13 +146,15 @@
     static final Interpolator TOUCH_RESPONSE_INTERPOLATOR =
             new PathInterpolator(0.3f, 0f, 0.1f, 1f);
 
+    private static final Interpolator THUMBNAIL_DOCK_INTERPOLATOR =
+            new PathInterpolator(0.85f, 0f, 1f, 1f);
+
     /**
      * Maximum duration for the clip reveal animation. This is used when there is a lot of movement
      * involved, to make it more understandable.
      */
     private static final int MAX_CLIP_REVEAL_TRANSITION_DURATION = 420;
     private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336;
-    private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 336;
     private static final long APP_TRANSITION_TIMEOUT_MS = 5000;
 
     private final Context mContext;
@@ -206,6 +215,7 @@
     private final Interpolator mThumbnailFadeOutInterpolator;
     private final Interpolator mLinearOutSlowInInterpolator;
     private final Interpolator mFastOutLinearInInterpolator;
+    private final Interpolator mFastOutSlowInInterpolator;
     private final Interpolator mClipHorizontalInterpolator = new PathInterpolator(0, 0, 0.4f, 1f);
 
     private final int mClipRevealTranslationY;
@@ -226,6 +236,8 @@
                 com.android.internal.R.interpolator.linear_out_slow_in);
         mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_linear_in);
+        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+                com.android.internal.R.interpolator.fast_out_slow_in);
         mConfigShortAnimTime = context.getResources().getInteger(
                 com.android.internal.R.integer.config_shortAnimTime);
         mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
@@ -812,12 +824,14 @@
      * Prepares the specified animation with a standard duration, interpolator, etc.
      */
     Animation prepareThumbnailAnimationWithDuration(Animation a, int appWidth, int appHeight,
-            int duration, Interpolator interpolator) {
+            long duration, Interpolator interpolator) {
         if (duration > 0) {
             a.setDuration(duration);
         }
         a.setFillAfter(true);
-        a.setInterpolator(interpolator);
+        if (interpolator != null) {
+            a.setInterpolator(interpolator);
+        }
         a.initialize(appWidth, appHeight, appWidth, appHeight);
         return a;
     }
@@ -866,55 +880,95 @@
      * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
      * when a thumbnail is specified with the pending animation override.
      */
-    Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, Bitmap thumbnailHeader,
-            final int taskId) {
+    Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets,
+            Bitmap thumbnailHeader, final int taskId, int orientation) {
         Animation a;
         final int thumbWidthI = thumbnailHeader.getWidth();
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
         final int thumbHeightI = thumbnailHeader.getHeight();
-        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
         final int appWidth = appRect.width();
 
         float scaleW = appWidth / thumbWidth;
-        float unscaledHeight = thumbHeight * scaleW;
         getNextAppTransitionStartRect(taskId, mTmpRect);
-        final float unscaledStartY = mTmpRect.top - (unscaledHeight - thumbHeight) / 2f;
-        final float toY = appRect.top + -unscaledStartY;
+        final float fromX;
+        final float fromY;
+        final float toX;
+        final float toY;
+        final float pivotX;
+        final float pivotY;
+        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+            fromX = mTmpRect.left;
+            fromY = mTmpRect.top;
+
+            // For the curved translate animation to work, the pivot points needs to be at the
+            // same absolute position as the one from the real surface.
+            toX = mTmpRect.width() / 2 * (scaleW - 1f) + appRect.left;
+            toY = appRect.height() / 2 * (1 - 1 / scaleW) + appRect.top;
+            pivotX = mTmpRect.width() / 2;
+            pivotY = appRect.height() / 2 / scaleW;
+        } else {
+            pivotX = 0;
+            pivotY = 0;
+            fromX = mTmpRect.left;
+            fromY = mTmpRect.top;
+            toX = appRect.left;
+            toY = appRect.top;
+        }
+        final long duration = getAspectScaleDuration();
+        final Interpolator interpolator = getAspectScaleInterpolator();
         if (mNextAppTransitionScaleUp) {
             // Animation up from the thumbnail to the full screen
-            Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
-                    mTmpRect.left + (thumbWidth / 2f), mTmpRect.top + (thumbHeight / 2f));
-            scale.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
-            scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
+            Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW, pivotX, pivotY);
+            scale.setInterpolator(interpolator);
+            scale.setDuration(duration);
             Animation alpha = new AlphaAnimation(1f, 0f);
-            alpha.setInterpolator(mThumbnailFadeOutInterpolator);
-            alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
-            final float toX = appRect.left + appRect.width() / 2 -
-                    (mTmpRect.left + thumbWidth / 2);
-            Animation translate = new TranslateAnimation(0, toX, 0, toY);
-            translate.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
-            translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
+            alpha.setInterpolator(mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
+                    ? THUMBNAIL_DOCK_INTERPOLATOR : mThumbnailFadeOutInterpolator);
+            alpha.setDuration(mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
+                    ? duration / 2
+                    : duration);
+            Animation translate = createCurvedMotion(fromX, toX, fromY, toY);
+            translate.setInterpolator(interpolator);
+            translate.setDuration(duration);
+
+            mTmpFromClipRect.set(0, 0, thumbWidthI, thumbHeightI);
+            mTmpToClipRect.set(appRect);
+
+            // Containing frame is in screen space, but we need the clip rect in the
+            // app space.
+            mTmpToClipRect.offsetTo(0, 0);
+            mTmpToClipRect.right = (int) (mTmpToClipRect.right / scaleW);
+            mTmpToClipRect.bottom = (int) (mTmpToClipRect.bottom / scaleW);
+
+            if (contentInsets != null) {
+                mTmpToClipRect.inset((int) (-contentInsets.left * scaleW),
+                        (int) (-contentInsets.top * scaleW),
+                        (int) (-contentInsets.right * scaleW),
+                        (int) (-contentInsets.bottom * scaleW));
+            }
+
+            Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
+            clipAnim.setInterpolator(interpolator);
+            clipAnim.setDuration(duration);
 
             // This AnimationSet uses the Interpolators assigned above.
             AnimationSet set = new AnimationSet(false);
             set.addAnimation(scale);
             set.addAnimation(alpha);
             set.addAnimation(translate);
+            set.addAnimation(clipAnim);
             a = set;
         } else {
             // Animation down from the full screen to the thumbnail
-            Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
-                    mTmpRect.left + (thumbWidth / 2f), mTmpRect.top + (thumbHeight / 2f));
-            scale.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
-            scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
+            Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f, pivotX, pivotY);
+            scale.setInterpolator(interpolator);
+            scale.setDuration(duration);
             Animation alpha = new AlphaAnimation(0f, 1f);
             alpha.setInterpolator(mThumbnailFadeInInterpolator);
-            alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
-            final float toX = appRect.left + appRect.width() / 2 -
-                    (mTmpRect.left + thumbWidth / 2);
-            Animation translate = new TranslateAnimation(toX, 0, toY, 0);
-            translate.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
-            translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
+            alpha.setDuration(duration);
+            Animation translate = createCurvedMotion(toX, fromX, toY, fromY);
+            translate.setInterpolator(interpolator);
+            translate.setDuration(duration);
 
             // This AnimationSet uses the Interpolators assigned above.
             AnimationSet set = new AnimationSet(false);
@@ -925,7 +979,48 @@
 
         }
         return prepareThumbnailAnimationWithDuration(a, appWidth, appRect.height(), 0,
-                TOUCH_RESPONSE_INTERPOLATOR);
+                null);
+    }
+
+    private Animation createCurvedMotion(float fromX, float toX, float fromY, float toY) {
+
+        // Almost no x-change - use linear animation
+        if (Math.abs(toX - fromX) < 1f || mNextAppTransition != TRANSIT_DOCK_TASK_FROM_RECENTS) {
+            return new TranslateAnimation(fromX, toX, fromY, toY);
+        } else {
+            final Path path = createCurvedPath(fromX, toX, fromY, toY);
+            return new CurvedTranslateAnimation(path);
+        }
+    }
+
+    private Path createCurvedPath(float fromX, float toX, float fromY, float toY) {
+        final Path path = new Path();
+        path.moveTo(fromX, fromY);
+
+        if (fromY > toY) {
+            // If the object needs to go up, move it in horizontal direction first, then vertical.
+            path.cubicTo(fromX, fromY, toX, 0.9f * fromY + 0.1f * toY, toX, toY);
+        } else {
+            // If the object needs to go down, move it in vertical direction first, then horizontal.
+            path.cubicTo(fromX, fromY, fromX, 0.1f * fromY + 0.9f * toY, toX, toY);
+        }
+        return path;
+    }
+
+    private long getAspectScaleDuration() {
+        if (mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+            return (long) (THUMBNAIL_APP_TRANSITION_DURATION * 1.35f);
+        } else {
+            return THUMBNAIL_APP_TRANSITION_DURATION;
+        }
+    }
+
+    private Interpolator getAspectScaleInterpolator() {
+        if (mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+            return mFastOutSlowInInterpolator;
+        } else {
+            return TOUCH_RESPONSE_INTERPOLATOR;
+        }
     }
 
     /**
@@ -943,17 +1038,23 @@
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
         final int thumbHeightI = mTmpRect.height();
         final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
-
-        // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
-        float scale = 1f;
-        int scaledTopDecor = 0;
+        final int thumbStartX = mTmpRect.left - containingFrame.left;
+        final int thumbStartY = mTmpRect.top - containingFrame.top;
 
         switch (thumbTransitState) {
-            case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
-                if (freeform) {
+            case THUMBNAIL_TRANSITION_ENTER_SCALE_UP:
+            case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
+                final boolean scaleUp = thumbTransitState == THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
+                if (freeform && scaleUp) {
                     a = createAspectScaledThumbnailEnterFreeformAnimationLocked(
                             containingFrame, surfaceInsets, taskId);
+                } else if (freeform) {
+                    a = createAspectScaledThumbnailExitFreeformAnimationLocked(
+                            containingFrame, surfaceInsets, taskId);
                 } else {
+                    AnimationSet set = new AnimationSet(true);
+
+                    // In portrait, we scale to fit the width
                     mTmpFromClipRect.set(containingFrame);
                     mTmpToClipRect.set(containingFrame);
 
@@ -964,26 +1065,61 @@
 
                     // Exclude insets region from the source clip.
                     mTmpFromClipRect.inset(contentInsets);
-
-                    // We scale the width and clip to the top/left square
-                    scale = thumbWidth / (appWidth - contentInsets.left - contentInsets.right);
-                    scaledTopDecor = (int) (scale * contentInsets.top);
-                    int unscaledThumbHeight = (int) (thumbHeight / scale);
-                    mTmpFromClipRect.bottom = mTmpFromClipRect.top + unscaledThumbHeight;
-
                     mNextAppTransitionInsets.set(contentInsets);
 
-                    Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
-                            computePivot(mTmpRect.left - containingFrame.left, scale),
-                            computePivot(mTmpRect.top - containingFrame.top, scale));
-                    Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
-                    Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
+                    if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+                        // We scale the width and clip to the top/left square
+                        // We scale the width and clip to the top/left square
+                        float scale = thumbWidth /
+                                (appWidth - contentInsets.left - contentInsets.right);
+                        int unscaledThumbHeight = (int) (thumbHeight / scale);
+                        mTmpFromClipRect.bottom = mTmpFromClipRect.top + unscaledThumbHeight;
 
-                    AnimationSet set = new AnimationSet(true);
-                    set.addAnimation(clipAnim);
-                    set.addAnimation(scaleAnim);
-                    set.addAnimation(translateAnim);
+                        mNextAppTransitionInsets.set(contentInsets);
+
+                        Animation scaleAnim = new ScaleAnimation(
+                                scaleUp ? scale : 1, scaleUp ? 1 : scale,
+                                scaleUp ? scale : 1, scaleUp ? 1 : scale,
+                                containingFrame.width() / 2f,
+                                containingFrame.height() / 2f + contentInsets.top);
+                        final float targetX = (mTmpRect.left - containingFrame.left);
+                        final float x = containingFrame.width() / 2f
+                                - containingFrame.width() / 2f * scale;
+                        final float targetY = (mTmpRect.top - containingFrame.top);
+                        final float y = containingFrame.height() / 2f
+                                - containingFrame.height() / 2f * scale;
+                        final float startX = targetX - x;
+                        final float startY = targetY - y;
+                        Animation clipAnim = scaleUp
+                                ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
+                                : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
+                        Animation translateAnim = scaleUp
+                                ? createCurvedMotion(startX, 0, startY - contentInsets.top, 0)
+                                : createCurvedMotion(0, startX, 0, startY - contentInsets.top);
+
+                        set.addAnimation(clipAnim);
+                        set.addAnimation(scaleAnim);
+                        set.addAnimation(translateAnim);
+
+                    } else {
+                        // In landscape, we don't scale at all and only crop
+                        mTmpFromClipRect.bottom = mTmpFromClipRect.top + thumbHeightI;
+                        mTmpFromClipRect.right = mTmpFromClipRect.left + thumbWidthI;
+
+                        Animation clipAnim = scaleUp
+                                ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
+                                : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
+                        Animation translateAnim = scaleUp
+                                ? createCurvedMotion(thumbStartX, 0,
+                                thumbStartY - contentInsets.top, 0)
+                                : createCurvedMotion(0, thumbStartX, 0,
+                                        thumbStartY - contentInsets.top);
+
+                        set.addAnimation(clipAnim);
+                        set.addAnimation(translateAnim);
+                    }
                     a = set;
+                    a.setZAdjustment(Animation.ZORDER_TOP);
                 }
                 break;
             }
@@ -1009,55 +1145,12 @@
                 }
                 break;
             }
-            case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
-                // App window scaling down from full screen
-                if (freeform) {
-                    a = createAspectScaledThumbnailExitFreeformAnimationLocked(
-                            containingFrame, surfaceInsets, taskId);
-                } else {
-                    mTmpFromClipRect.set(containingFrame);
-                    mTmpToClipRect.set(containingFrame);
-
-                    // Containing frame is in screen space, but we need the clip rect in the
-                    // app space.
-                    mTmpFromClipRect.offsetTo(0, 0);
-                    mTmpToClipRect.offsetTo(0, 0);
-
-                    // Exclude insets region from the target clip.
-                    mTmpToClipRect.inset(contentInsets);
-
-                    // We scale the width and clip to the top/left square
-                    scale = thumbWidth / (appWidth - contentInsets.left - contentInsets.right);
-                    scaledTopDecor = (int) (scale * contentInsets.top);
-                    int unscaledThumbHeight = (int) (thumbHeight / scale);
-                    mTmpToClipRect.bottom = mTmpToClipRect.top + unscaledThumbHeight;
-
-                    mNextAppTransitionInsets.set(contentInsets);
-
-                    Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
-                            computePivot(mTmpRect.left - containingFrame.left, scale),
-                            computePivot(mTmpRect.top - containingFrame.top, scale));
-                    Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
-                    Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
-
-                    AnimationSet set = new AnimationSet(true);
-                    set.addAnimation(clipAnim);
-                    set.addAnimation(scaleAnim);
-                    set.addAnimation(translateAnim);
-
-                    a = set;
-                    a.setZAdjustment(Animation.ZORDER_TOP);
-                }
-                break;
-            }
             default:
                 throw new RuntimeException("Invalid thumbnail transition state");
         }
 
-        int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
-                THUMBNAIL_APP_TRANSITION_DURATION);
-        return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
-                TOUCH_RESPONSE_INTERPOLATOR);
+        return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight,
+                getAspectScaleDuration(), getAspectScaleInterpolator());
     }
 
     private Animation createAspectScaledThumbnailEnterFreeformAnimationLocked(Rect frame,
@@ -1411,6 +1504,7 @@
                             ? WindowAnimation_activityCloseEnterAnimation
                             : WindowAnimation_activityCloseExitAnimation;
                     break;
+                case TRANSIT_DOCK_TASK_FROM_RECENTS:
                 case TRANSIT_TASK_OPEN:
                     animAttr = enter
                             ? WindowAnimation_taskOpenEnterAnimation
@@ -1467,6 +1561,14 @@
         return a;
     }
 
+    int getAppStackClipMode() {
+        return mNextAppTransition == TRANSIT_ACTIVITY_RELAUNCH
+                || mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
+                || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL
+                ? STACK_CLIP_NONE
+                : STACK_CLIP_AFTER_ANIM;
+    }
+
     void postAnimationCallback() {
         if (mNextAppTransitionCallback != null) {
             mService.mH.sendMessage(mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK,
@@ -1686,6 +1788,9 @@
             case TRANSIT_ACTIVITY_RELAUNCH: {
                 return "TRANSIT_ACTIVITY_RELAUNCH";
             }
+            case TRANSIT_DOCK_TASK_FROM_RECENTS: {
+                return "TRANSIT_DOCK_TASK_FROM_RECENTS";
+            }
             default: {
                 return "<UNKNOWN>";
             }
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 3a5dec9..aae52e8 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -23,6 +23,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
 
 import android.graphics.Matrix;
 import android.util.Slog;
@@ -76,8 +77,6 @@
     // requires that the duration of the two animations are the same.
     SurfaceControl thumbnail;
     int thumbnailTransactionSeq;
-    int thumbnailX;
-    int thumbnailY;
     int thumbnailLayer;
     int thumbnailForceAboveLayer;
     Animation thumbnailAnimation;
@@ -106,6 +105,7 @@
     boolean usingTransferredAnimation = false;
 
     private boolean mSkipFirstFrame = false;
+    private int mStackClip = STACK_CLIP_BEFORE_ANIM;
 
     static final Animation sDummyAnimation = new DummyAnimation();
 
@@ -115,7 +115,8 @@
         mAnimator = mService.mAnimator;
     }
 
-    public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame) {
+    public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame,
+            int stackClip) {
         if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
                 + ": " + anim + " wxh=" + width + "x" + height
                 + " isVisible=" + mAppToken.isVisible());
@@ -142,6 +143,7 @@
         transformation.clear();
         transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
         hasTransformation = true;
+        mStackClip = stackClip;
 
         this.mSkipFirstFrame = skipFirstFrame;
 
@@ -186,6 +188,7 @@
             mAppToken.allDrawn = false;
             mAppToken.deferClearAllDrawn = false;
         }
+        mStackClip = STACK_CLIP_BEFORE_ANIM;
     }
 
     public boolean isAnimating() {
@@ -201,6 +204,10 @@
         deferThumbnailDestruction = false;
     }
 
+    int getStackClip() {
+        return mStackClip;
+    }
+
     void transferCurrentAnimation(
             AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) {
 
@@ -245,7 +252,6 @@
         thumbnailTransformation.clear();
         final long animationFrameTime = getAnimationFrameTime(thumbnailAnimation, currentTime);
         thumbnailAnimation.getTransformation(animationFrameTime, thumbnailTransformation);
-        thumbnailTransformation.getMatrix().preTranslate(thumbnailX, thumbnailY);
 
         ScreenRotationAnimation screenRotationAnimation =
                 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
@@ -279,6 +285,7 @@
         }
         thumbnail.setMatrix(tmpFloats[Matrix.MSCALE_X], tmpFloats[Matrix.MSKEW_Y],
                 tmpFloats[Matrix.MSKEW_X], tmpFloats[Matrix.MSCALE_Y]);
+        thumbnail.setWindowCrop(thumbnailTransformation.getClipRect());
     }
 
     /**
@@ -452,8 +459,6 @@
         }
         if (thumbnail != null) {
             pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail);
-                    pw.print(" x="); pw.print(thumbnailX);
-                    pw.print(" y="); pw.print(thumbnailY);
                     pw.print(" layer="); pw.println(thumbnailLayer);
             pw.print(prefix); pw.print("thumbnailAnimation="); pw.println(thumbnailAnimation);
             pw.print(prefix); pw.print("thumbnailTransformation=");
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 36e8bbb..6741aba 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -96,6 +96,7 @@
     private final Interpolator mMinimizedDockInterpolator;
     private float mMaximizeMeetFraction;
     private final Rect mTouchRegion = new Rect();
+    private boolean mAdjustingForIme;
 
     DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) {
         mService = service;
@@ -173,6 +174,14 @@
         return mLastVisibility;
     }
 
+    void setAdjustingForIme(boolean adjusting) {
+        mAdjustingForIme = adjusting;
+    }
+
+    boolean isAdjustingForIme() {
+        return mAdjustingForIme;
+    }
+
     void positionDockedStackedDivider(Rect frame) {
         TaskStack stack = mDisplayContent.getDockedStackLocked();
         if (stack == null) {
diff --git a/services/core/java/com/android/server/wm/DragResizeMode.java b/services/core/java/com/android/server/wm/DragResizeMode.java
new file mode 100644
index 0000000..08acf9d
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DragResizeMode.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+
+/**
+ * Describes the mode in which a window is drag resizing.
+ */
+class DragResizeMode {
+
+    /**
+     * Freeform mode: Client surface is fullscreen, and client is responsible to draw window at
+     * the correct position.
+     */
+    static final int DRAG_RESIZE_MODE_FREEFORM = 0;
+
+    /**
+     * Mode for resizing the docked (and adjacent) stack: Client surface is fullscreen, but window
+     * is drawn at (0, 0), window manager is responsible for positioning the surface when draging.
+     */
+    static final int DRAG_RESIZE_MODE_DOCKED_DIVIDER = 1;
+
+    static boolean isModeAllowedForStack(int stackId, int mode) {
+        switch (mode) {
+            case DRAG_RESIZE_MODE_FREEFORM:
+                return stackId == FREEFORM_WORKSPACE_STACK_ID;
+            case DRAG_RESIZE_MODE_DOCKED_DIVIDER:
+                return stackId == DOCKED_STACK_ID
+                        || stackId == FULLSCREEN_WORKSPACE_STACK_ID
+                        || stackId == HOME_STACK_ID;
+            default:
+                return false;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index f097eb2..4e8f19e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -18,8 +18,6 @@
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
@@ -103,6 +101,7 @@
 
     // Whether the task is currently being drag-resized
     private boolean mDragResizing;
+    private int mDragResizeMode;
 
     private boolean mHomeTask;
 
@@ -140,41 +139,7 @@
             final String text =
                     mService.mContext.getString(R.string.dock_non_resizeble_failed_to_dock_text);
             mService.mH.obtainMessage(SHOW_NON_RESIZEABLE_DOCK_TOAST, 0, 0, text).sendToTarget();
-            return;
         }
-
-        final int dockSide = mStack.getDockSide();
-        if (mResizeMode != RESIZE_MODE_FORCE_RESIZEABLE || dockSide == DOCKED_INVALID) {
-            return;
-        }
-
-        int xOffset = 0;
-        int yOffset = 0;
-        mStack.getBounds(mTmpRect);
-
-        if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
-            // The toast was originally placed at the bottom and centered. To place it at the
-            // bottom-center of the stack, we offset it horizontally by the diff between the center
-            // of the stack bounds vs. the center of the screen.
-            displayContent.getLogicalDisplayRect(mTmpRect2);
-            xOffset = mTmpRect.centerX() - mTmpRect2.centerX();
-        } else if (dockSide == DOCKED_TOP) {
-            // The toast was originally placed at the bottom and centered. To place it at the bottom
-            // center of the top stack, we offset it vertically by the diff between the bottom of
-            // the stack bounds vs. the bottom of the content rect.
-            //
-            // Note here we use the content rect instead of the display rect, as we want the toast's
-            // distance to the dock divider (when it's placed at the top half) to be the same as
-            // it's distance to the top of the navigation bar (when it's placed at the bottom).
-
-            // We don't adjust for DOCKED_BOTTOM case since it's already at the bottom.
-            displayContent.getContentRect(mTmpRect2);
-            yOffset = mTmpRect2.bottom - mTmpRect.bottom;
-        }
-        final String text =
-                mService.mContext.getString(R.string.dock_forced_resizable);
-        mService.mH.obtainMessage(SHOW_NON_RESIZEABLE_DOCK_TOAST,
-                xOffset, yOffset, text).sendToTarget();
     }
 
     void addAppToken(int addPos, AppWindowToken wtoken, int resizeMode, boolean homeTask) {
@@ -543,9 +508,14 @@
         mStack.getDisplayContent().getLogicalDisplayRect(out);
     }
 
-    void setDragResizing(boolean dragResizing) {
+    void setDragResizing(boolean dragResizing, int dragResizeMode) {
         if (mDragResizing != dragResizing) {
+            if (!DragResizeMode.isModeAllowedForStack(mStack.mStackId, dragResizeMode)) {
+                throw new IllegalArgumentException("Drag resize mode not allow for stack stackId="
+                        + mStack.mStackId + " dragResizeMode=" + dragResizeMode);
+            }
             mDragResizing = dragResizing;
+            mDragResizeMode = dragResizeMode;
             resetDragResizingChangeReported();
         }
     }
@@ -564,6 +534,10 @@
         return mDragResizing || (mStack != null && mStack.isDragResizing());
     }
 
+    int getDragResizeMode() {
+        return mDragResizeMode;
+    }
+
     void updateDisplayInfo(final DisplayContent displayContent) {
         if (displayContent == null) {
             return;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 92701de..ae70aa8 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -29,6 +29,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.dipToPixel;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
 
@@ -379,7 +380,7 @@
 
     private void endDragLocked() {
         mResizing = false;
-        mTask.setDragResizing(false);
+        mTask.setDragResizing(false, DRAG_RESIZE_MODE_FREEFORM);
     }
 
     /** Returns true if the move operation should be ended. */
@@ -409,7 +410,7 @@
                 bottom = Math.max(top + mMinVisibleHeight, bottom + deltaY);
             }
             mWindowDragBounds.set(left, top, right, bottom);
-            mTask.setDragResizing(true);
+            mTask.setDragResizing(true, DRAG_RESIZE_MODE_FREEFORM);
             return false;
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index c667767..8d67771 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -200,10 +200,11 @@
      * @param bounds The adjusted bounds.
      * @param keepInsets Whether to keep the insets from the original bounds or to calculate new
      *                   ones depending on the adjusted bounds.
+     * @return true if the adjusted bounds has changed.
      */
-    private void setAdjustedBounds(Rect bounds, boolean keepInsets) {
+    private boolean setAdjustedBounds(Rect bounds, boolean keepInsets) {
         if (mAdjustedBounds.equals(bounds)) {
-            return;
+            return false;
         }
 
         mAdjustedBounds.set(bounds);
@@ -211,6 +212,7 @@
         alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : mBounds,
                 adjusted && keepInsets ? mBounds : null);
         mDisplayContent.layoutNeeded = true;
+        return true;
     }
 
     private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
@@ -794,7 +796,9 @@
     void setAdjustedForIme(WindowState imeWin) {
         mAdjustedForIme = true;
         mImeWin = imeWin;
-        updateAdjustedBounds();
+        if (updateAdjustedBounds()) {
+            getDisplayContent().mDividerControllerLocked.setAdjustingForIme(true);
+        }
     }
 
     /**
@@ -803,7 +807,9 @@
     void resetAdjustedForIme() {
         mAdjustedForIme = false;
         mImeWin = null;
-        updateAdjustedBounds();
+        if (updateAdjustedBounds()) {
+            getDisplayContent().mDividerControllerLocked.setAdjustingForIme(true);
+        }
     }
 
     /**
@@ -920,7 +926,7 @@
     /**
      * Updates the adjustment depending on it's current state.
      */
-    void updateAdjustedBounds() {
+    boolean updateAdjustedBounds() {
         boolean adjust = false;
         if (mMinimizeAmount != 0f) {
             adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
@@ -931,7 +937,7 @@
             mTmpAdjustedBounds.setEmpty();
             mLastContentBounds.setEmpty();
         }
-        setAdjustedBounds(mTmpAdjustedBounds, isAdjustedForMinimizedDockedStack());
+        return setAdjustedBounds(mTmpAdjustedBounds, isAdjustedForMinimizedDockedStack());
     }
 
     boolean isAdjustedForMinimizedDockedStack() {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index f243761..eae7838 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -36,6 +36,8 @@
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
 import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
@@ -406,7 +408,8 @@
 
                             Animation a = mPolicy.createForceHideEnterAnimation(false,
                                     keyguardGoingAwayToShade);
-                            winAnimator.setAnimation(a, mPostKeyguardExitAnimation.getStartTime());
+                            winAnimator.setAnimation(a, mPostKeyguardExitAnimation.getStartTime(),
+                                    STACK_CLIP_BEFORE_ANIM);
                             winAnimator.mKeyguardGoingAwayAnimation = true;
                             winAnimator.mKeyguardGoingAwayWithWallpaper
                                     = keyguardGoingAwayWithWallpaper;
@@ -445,7 +448,7 @@
             }
 
             final AppWindowToken atoken = win.mAppToken;
-            if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
+            if (winAnimator.mDrawState == READY_TO_SHOW) {
                 if (atoken == null || atoken.allDrawn) {
                     if (winAnimator.performShowLocked()) {
                         setPendingLayoutChanges(displayId,
@@ -487,7 +490,7 @@
                     if (a != null) {
                         if (DEBUG_KEYGUARD) Slog.v(TAG,
                                 "Starting keyguard exit animation on window " + winAnimator.mWin);
-                        winAnimator.setAnimation(a);
+                        winAnimator.setAnimation(a, STACK_CLIP_BEFORE_ANIM);
                         winAnimator.mKeyguardGoingAwayAnimation = true;
                         winAnimator.mKeyguardGoingAwayWithWallpaper
                                 = keyguardGoingAwayWithWallpaper;
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index d843a8c..f76f03f 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -77,28 +77,22 @@
             int oldLayer = w.mLayer;
             if (w.mBaseLayer == curBaseLayer || w.mIsImWindow || (i > 0 && w.mIsWallpaper)) {
                 curLayer += WINDOW_LAYER_MULTIPLIER;
-                w.mLayer = curLayer;
             } else {
                 curBaseLayer = curLayer = w.mBaseLayer;
-                w.mLayer = curLayer;
             }
-            if (w.mLayer != oldLayer) {
-                layerChanged = true;
-                anyLayerChanged = true;
-            }
+            assignAnimLayer(w, curLayer);
 
-            final WindowStateAnimator winAnimator = w.mWinAnimator;
-            oldLayer = winAnimator.mAnimLayer;
-            winAnimator.mAnimLayer = w.mLayer + w.getAnimLayerAdjustment() +
-                    getSpecialWindowAnimLayerAdjustment(w);
-            if (winAnimator.mAnimLayer != oldLayer) {
+            // TODO: Preserved old behavior of code here but not sure comparing
+            // oldLayer to mAnimLayer and mLayer makes sense...though the
+            // worst case would be unintentionalp layer reassignment.
+            if (w.mLayer != oldLayer || w.mWinAnimator.mAnimLayer != oldLayer) {
                 layerChanged = true;
                 anyLayerChanged = true;
             }
 
             if (w.mAppToken != null) {
                 mHighestApplicationLayer = Math.max(mHighestApplicationLayer,
-                        winAnimator.mAnimLayer);
+                        w.mWinAnimator.mAnimLayer);
             }
             collectSpecialWindows(w);
 
@@ -223,12 +217,21 @@
 
     private int assignAndIncreaseLayerIfNeeded(WindowState win, int layer) {
         if (win != null) {
-            win.mLayer = layer;
-            win.mWinAnimator.mAnimLayer = layer;
+            assignAnimLayer(win, layer);
             layer++;
         }
         return layer;
     }
+    
+    private void assignAnimLayer(WindowState w, int layer) {
+        w.mLayer = layer;
+        w.mWinAnimator.mAnimLayer = w.mLayer + w.getAnimLayerAdjustment() +
+                    getSpecialWindowAnimLayerAdjustment(w);
+        if (w.mAppToken != null && w.mAppToken.mAppAnimator.thumbnailForceAboveLayer > 0
+                && w.mWinAnimator.mAnimLayer > w.mAppToken.mAppAnimator.thumbnailForceAboveLayer) {
+            w.mAppToken.mAppAnimator.thumbnailForceAboveLayer = w.mWinAnimator.mAnimLayer;
+        }
+    }
 
     void dump(PrintWriter pw, String s) {
         if (mInputMethodAnimLayerAdjustment != 0 ||
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 14291ca..5771d69 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -202,6 +202,8 @@
 import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
@@ -236,6 +238,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
 
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
@@ -798,7 +801,13 @@
             = new WindowManagerInternal.AppTransitionListener() {
 
         @Override
+        public void onAppTransitionCancelledLocked() {
+            mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_CANCELLED);
+        }
+
+        @Override
         public void onAppTransitionFinishedLocked(IBinder token) {
+            mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_FINISHED);
             AppWindowToken atoken = findAppWindowToken(token);
             if (atoken == null) {
                 return;
@@ -2920,9 +2929,9 @@
             }
         }
         final boolean freeformResizing = win.isDragResizing()
-                && win.getResizeMode() == WindowState.DRAG_RESIZE_MODE_FREEFORM;
+                && win.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
         final boolean dockedResizing = win.isDragResizing()
-                && win.getResizeMode() == WindowState.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+                && win.getResizeMode() == DRAG_RESIZE_MODE_DOCKED_DIVIDER;
         result |= freeformResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM : 0;
         result |= dockedResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED : 0;
         if (win.isAnimatingWithSavedSurface()) {
@@ -3039,7 +3048,7 @@
                 final int containingWidth = frame.width();
                 final int containingHeight = frame.height();
                 atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight,
-                        mAppTransition.canSkipFirstFrame());
+                        mAppTransition.canSkipFirstFrame(), mAppTransition.getAppStackClipMode());
             }
         } else {
             atoken.mAppAnimator.clearAnimation();
@@ -4024,8 +4033,6 @@
                 wAppAnimator.thumbnail.destroy();
             }
             wAppAnimator.thumbnail = tAppAnimator.thumbnail;
-            wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
-            wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
             wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
             wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
             tAppAnimator.thumbnail = null;
@@ -4989,6 +4996,23 @@
         }
     }
 
+    /**
+     * Puts a specific task into docked drag resizing mode. See {@link DragResizeMode}.
+     *
+     * @param taskId The id of the task to put into drag resize mode.
+     * @param resizing Whether to put the task into drag resize mode.
+     */
+    public void setTaskDockedResizing(int taskId, boolean resizing) {
+        synchronized (mWindowMap) {
+            Task task = mTaskIdToTask.get(taskId);
+            if (task == null) {
+                throw new IllegalArgumentException("setTaskDockedResizing: taskId " + taskId
+                        + " not found.");
+            }
+            task.setDragResizing(resizing, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
+        }
+    }
+
     public void scrollTask(int taskId, Rect bounds) {
         synchronized (mWindowMap) {
             Task task = mTaskIdToTask.get(taskId);
@@ -5735,7 +5759,7 @@
         if (mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay)
                 && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false)
-                && Build.HARDWARE.contains("goldfish")) {
+                && Build.IS_EMULATOR) {
             mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY));
         }
     }
@@ -7352,6 +7376,30 @@
         }
     }
 
+    private void adjustForImeIfNeeded(final DisplayContent displayContent) {
+        final WindowState imeWin = mInputMethodWindow;
+        final TaskStack focusedStack =
+                mCurrentFocus != null ? mCurrentFocus.getStack() : null;
+        if (imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
+                && isStackVisibleLocked(DOCKED_STACK_ID)
+                && focusedStack != null
+                && focusedStack.getDockSide() == DOCKED_BOTTOM){
+            final ArrayList<TaskStack> stacks = displayContent.getStacks();
+            for (int i = stacks.size() - 1; i >= 0; --i) {
+                final TaskStack stack = stacks.get(i);
+                if (stack.isVisibleLocked()) {
+                    stack.setAdjustedForIme(imeWin);
+                }
+            }
+        } else {
+            final ArrayList<TaskStack> stacks = displayContent.getStacks();
+            for (int i = stacks.size() - 1; i >= 0; --i) {
+                final TaskStack stack = stacks.get(i);
+                stack.resetAdjustedForIme();
+            }
+        }
+    }
+
     // -------------------------------------------------------------
     // Drag and drop
     // -------------------------------------------------------------
@@ -7670,7 +7718,9 @@
         public static final int WINDOW_REPLACEMENT_TIMEOUT = 46;
 
         public static final int NOTIFY_APP_TRANSITION_STARTING = 47;
-        public static final int NOTIFY_STARTING_WINDOW_DRAWN = 48;
+        public static final int NOTIFY_APP_TRANSITION_CANCELLED = 48;
+        public static final int NOTIFY_APP_TRANSITION_FINISHED = 49;
+        public static final int NOTIFY_STARTING_WINDOW_DRAWN = 50;
 
         /**
          * Used to denote that an integer field in a message will not be used.
@@ -8209,30 +8259,8 @@
                 case UPDATE_DOCKED_STACK_DIVIDER: {
                     synchronized (mWindowMap) {
                         final DisplayContent displayContent = getDefaultDisplayContentLocked();
-
                         displayContent.getDockedDividerController().reevaluateVisibility(false);
-
-                        final WindowState imeWin = mInputMethodWindow;
-                        final TaskStack focusedStack =
-                                mCurrentFocus != null ? mCurrentFocus.getStack() : null;
-                        if (imeWin != null && imeWin.isVisibleNow()
-                                && isStackVisibleLocked(DOCKED_STACK_ID)
-                                && focusedStack != null
-                                && focusedStack.getDockSide() == DOCKED_BOTTOM){
-                            final ArrayList<TaskStack> stacks = displayContent.getStacks();
-                            for (int i = stacks.size() - 1; i >= 0; --i) {
-                                final TaskStack stack = stacks.get(i);
-                                if (stack.isVisibleLocked()) {
-                                    stack.setAdjustedForIme(imeWin);
-                                }
-                            }
-                        } else {
-                            final ArrayList<TaskStack> stacks = displayContent.getStacks();
-                            for (int i = stacks.size() - 1; i >= 0; --i) {
-                                final TaskStack stack = stacks.get(i);
-                                stack.resetAdjustedForIme();
-                            }
-                        }
+                        adjustForImeIfNeeded(displayContent);
                     }
                 }
                 break;
@@ -8273,6 +8301,14 @@
                     mAmInternal.notifyAppTransitionStarting(msg.arg1);
                 }
                 break;
+                case NOTIFY_APP_TRANSITION_CANCELLED: {
+                    mAmInternal.notifyAppTransitionCancelled();
+                }
+                break;
+                case NOTIFY_APP_TRANSITION_FINISHED: {
+                    mAmInternal.notifyAppTransitionFinished();
+                }
+                break;
                 case NOTIFY_STARTING_WINDOW_DRAWN: {
                     mAmInternal.notifyStartingWindowDrawn();
                 }
@@ -8971,7 +9007,7 @@
                                 + ", mDrawState=DRAW_PENDING in " + w
                                 + ", surfaceController " + winAnimator.mSurfaceController);
                     }
-                    winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
+                    winAnimator.mDrawState = DRAW_PENDING;
                     if (w.mAppToken != null) {
                         w.mAppToken.allDrawn = false;
                         w.mAppToken.deferClearAllDrawn = false;
@@ -10515,9 +10551,9 @@
     }
 
     @Override
-    public void requestAppKeyboardShortcuts(IResultReceiver receiver) {
+    public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
         try {
-            getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver);
+            getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver, deviceId);
         } catch (RemoteException e) {
         }
     }
@@ -10785,7 +10821,7 @@
                     final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs);
                     if (win.isVisibleLw()
                             && (win.mAppToken != null || isForceHiding)) {
-                        win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
+                        win.mWinAnimator.mDrawState = DRAW_PENDING;
                         // Force add to mResizingWindows.
                         win.mLastContentInsets.set(-1, -1, -1, -1);
                         mWaitingForDrawn.add(win);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1695615..0866c03 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -71,6 +71,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
@@ -87,6 +88,8 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
@@ -123,9 +126,6 @@
     // to capture touch events in that area.
     static final int RESIZE_HANDLE_WIDTH_IN_DP = 30;
 
-    static final int DRAG_RESIZE_MODE_FREEFORM = 0;
-    static final int DRAG_RESIZE_MODE_DOCKED_DIVIDER = 1;
-
     static final boolean DEBUG_DISABLE_SAVING_SURFACES = false;
 
     final WindowManagerService mService;
@@ -655,8 +655,7 @@
         }
 
         if (mInsetFrame.isEmpty()  && (fullscreenTask
-                || (isChildWindow() && (mAttrs.privateFlags
-                        & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0))) {
+                || layoutInParentFrame())) {
             // We use the parent frame as the containing frame for fullscreen and child windows
             mContainingFrame.set(pf);
             mDisplayFrame.set(df);
@@ -756,20 +755,10 @@
             mVisibleFrame.set(mContentFrame);
             mStableFrame.set(mContentFrame);
         } else if (mAttrs.type == TYPE_DOCK_DIVIDER) {
-            if (isVisibleLw() || mWinAnimator.isAnimating()) {
-                // We don't adjust the dock divider frame for reasons other than performance. The
-                // real reason is that if it gets adjusted before it is shown for the first time,
-                // it would get size (0, 0). This causes a problem when we finally show the dock
-                // divider and try to draw to it. We do set the surface size at that moment to
-                // the correct size, but it's too late for the Surface Flinger to make it
-                // available for view rendering and as a result the renderer receives size 1, 1.
-                // This way we just keep the divider at the original size and Surface Flinger
-                // will return the correct value to the renderer.
-                mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame);
-                mContentFrame.set(mFrame);
-                if (!mFrame.equals(mLastFrame)) {
-                    mMovedByResize = true;
-                }
+            mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame);
+            mContentFrame.set(mFrame);
+            if (!mFrame.equals(mLastFrame)) {
+                mMovedByResize = true;
             }
         } else {
             mContentFrame.set(Math.max(mContentFrame.left, frame.left),
@@ -810,38 +799,44 @@
             mContentInsets.setEmpty();
             mVisibleInsets.setEmpty();
         } else {
+            // Using mContentInsets as a temp rect. It is safe because we're setting it below.
+            getDisplayContent().getLogicalDisplayRect(mContentInsets);
+            // Override right and/or bottom insets in case if the frame doesn't fit the screen in
+            // non-fullscreen mode.
+            boolean overrideRightInset = !fullscreenTask && mFrame.right > mContentInsets.right;
+            boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mContentInsets.bottom;
             mContentInsets.set(mContentFrame.left - frame.left,
                     mContentFrame.top - frame.top,
-                    frame.right - mContentFrame.right,
-                    frame.bottom - mContentFrame.bottom);
+                    overrideRightInset ? 0 : frame.right - mContentFrame.right,
+                    overrideBottomInset ? 0 : frame.bottom - mContentFrame.bottom);
 
             mVisibleInsets.set(mVisibleFrame.left - frame.left,
                     mVisibleFrame.top - frame.top,
-                    frame.right - mVisibleFrame.right,
-                    frame.bottom - mVisibleFrame.bottom);
+                    overrideRightInset ? 0 : frame.right - mVisibleFrame.right,
+                    overrideBottomInset ? 0 : frame.bottom - mVisibleFrame.bottom);
 
             mStableInsets.set(Math.max(mStableFrame.left - frame.left, 0),
                     Math.max(mStableFrame.top - frame.top, 0),
-                    Math.max(frame.right - mStableFrame.right, 0),
-                    Math.max(frame.bottom - mStableFrame.bottom, 0));
+                    overrideRightInset ? 0 : Math.max(frame.right - mStableFrame.right, 0),
+                    overrideBottomInset ? 0 :  Math.max(frame.bottom - mStableFrame.bottom, 0));
         }
 
         if (!mInsetFrame.isEmpty()) {
             mContentFrame.set(mFrame);
             mContentFrame.top += mContentInsets.top;
-            mContentFrame.bottom += mContentInsets.bottom;
+            mContentFrame.bottom -= mContentInsets.bottom;
             mContentFrame.left += mContentInsets.left;
-            mContentFrame.right += mContentInsets.right;
+            mContentFrame.right -= mContentInsets.right;
             mVisibleFrame.set(mFrame);
             mVisibleFrame.top += mVisibleInsets.top;
-            mVisibleFrame.bottom += mVisibleInsets.bottom;
+            mVisibleFrame.bottom -= mVisibleInsets.bottom;
             mVisibleFrame.left += mVisibleInsets.left;
-            mVisibleFrame.right += mVisibleInsets.right;
+            mVisibleFrame.right -= mVisibleInsets.right;
             mStableFrame.set(mFrame);
             mStableFrame.top += mStableInsets.top;
-            mStableFrame.bottom += mStableInsets.bottom;
+            mStableFrame.bottom -= mStableInsets.bottom;
             mStableFrame.left += mStableInsets.left;
-            mStableFrame.right += mStableInsets.right;
+            mStableFrame.right -= mStableInsets.right;
         }
         mCompatFrame.set(mFrame);
         if (mEnforceSizeCompat) {
@@ -875,7 +870,7 @@
                 + "): frame=" + mFrame.toShortString()
                 + " ci=" + mContentInsets.toShortString()
                 + " vi=" + mVisibleInsets.toShortString()
-                + " vi=" + mStableInsets.toShortString()
+                + " si=" + mStableInsets.toShortString()
                 + " of=" + mOutsets.toShortString());
     }
 
@@ -1309,7 +1304,7 @@
      */
     boolean hasMoved() {
         return mHasSurface && (mContentChanged || mMovedByResize)
-                && !mAnimatingExit && !mWinAnimator.mLastHidden && mService.okToDisplay()
+                && !mAnimatingExit && mService.okToDisplay()
                 && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left)
                 && (mAttachedWindow == null || !mAttachedWindow.hasMoved());
     }
@@ -1883,6 +1878,13 @@
     }
 
     private boolean shouldSaveSurface() {
+        if ((mAttrs.flags & FLAG_SECURE) != 0) {
+            // We don't save secure surfaces since their content shouldn't be shown while the app
+            // isn't on screen and content might leak through during the transition animation with
+            // saved surface.
+            return false;
+        }
+
         if (ActivityManager.isLowRamDeviceStatic()) {
             // Don't save surfaces on Svelte devices.
             return false;
@@ -2251,7 +2253,7 @@
         return mResizeMode;
     }
 
-    private boolean computeDragResizing() {
+    boolean computeDragResizing() {
         final Task task = getTask();
         if (task == null) {
             return false;
@@ -2281,9 +2283,14 @@
             return;
         }
         mDragResizing = resizing;
-        mResizeMode = mDragResizing && mDisplayContent.mDividerControllerLocked.isResizing()
-                ? DRAG_RESIZE_MODE_DOCKED_DIVIDER
-                : DRAG_RESIZE_MODE_FREEFORM;
+        final Task task = getTask();
+        if (task != null && task.isDragResizing()) {
+            mResizeMode = task.getDragResizeMode();
+        } else {
+            mResizeMode = mDragResizing && mDisplayContent.mDividerControllerLocked.isResizing()
+                    ? DRAG_RESIZE_MODE_DOCKED_DIVIDER
+                    : DRAG_RESIZE_MODE_FREEFORM;
+        }
     }
 
     boolean isDragResizing() {
@@ -2521,7 +2528,7 @@
         final int ph = mContainingFrame.height();
         final Task task = getTask();
         final boolean nonFullscreenTask = inMultiWindowMode();
-        final boolean fitToDisplay = task != null && !task.isFloating();
+        final boolean fitToDisplay = task != null && !task.isFloating() && !layoutInParentFrame();
         float x, y;
         int w,h;
 
@@ -2595,6 +2602,10 @@
         return mAttachedWindow != null;
     }
 
+    boolean layoutInParentFrame() {
+        return isChildWindow() && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0;
+    }
+
     void setReplacing(boolean animate) {
         if ((mAttrs.privateFlags & PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH) != 0
                 || mAttrs.type == TYPE_APPLICATION_STARTING) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 41eafe7..1e103f0 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -20,6 +20,8 @@
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
@@ -38,8 +40,6 @@
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
 import static com.android.server.wm.WindowManagerService.localLOGV;
 import static com.android.server.wm.WindowManagerService.logWithStack;
-import static com.android.server.wm.WindowState.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
-import static com.android.server.wm.WindowState.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
 
@@ -75,6 +75,25 @@
     static final String TAG = TAG_WITH_CLASS_NAME ? "WindowStateAnimator" : TAG_WM;
     static final int WINDOW_FREEZE_LAYER = TYPE_LAYER_MULTIPLIER * 200;
 
+    /**
+     * Mode how the window gets clipped by the stack bounds during an animation: The clipping should
+     * be applied after applying the animation transformation, i.e. the stack bounds don't move
+     * during the animation.
+     */
+    static final int STACK_CLIP_AFTER_ANIM = 0;
+
+    /**
+     * Mode how the window gets clipped by the stack bounds: The clipping should be applied before
+     * applying the animation transformation, i.e. the stack bounds move with the window.
+     */
+    static final int STACK_CLIP_BEFORE_ANIM = 1;
+
+    /**
+     * Mode how window gets clipped by the stack bounds during an animation: Don't clip the window
+     * by the stack bounds.
+     */
+    static final int STACK_CLIP_NONE = 2;
+
     // Unchanging local convenience fields.
     final WindowManagerService mService;
     final WindowState mWin;
@@ -100,6 +119,7 @@
     int mLastLayer;
     long mAnimationStartTime;
     long mLastAnimationTime;
+    int mStackClip = STACK_CLIP_BEFORE_ANIM;
 
     /**
      * Set when we have changed the size of the surface, to know that
@@ -128,7 +148,9 @@
     boolean mHasClipRect;
     Rect mClipRect = new Rect();
     Rect mTmpClipRect = new Rect();
+    Rect mTmpFinalClipRect = new Rect();
     Rect mLastClipRect = new Rect();
+    Rect mLastFinalClipRect = new Rect();
     Rect mTmpStackBounds = new Rect();
 
     /**
@@ -226,7 +248,7 @@
         mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
     }
 
-    public void setAnimation(Animation anim, long startTime) {
+    public void setAnimation(Animation anim, long startTime, int stackClip) {
         if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
         mAnimating = false;
         mLocalAnimating = false;
@@ -238,10 +260,15 @@
         mTransformation.setAlpha(mLastHidden ? 0 : 1);
         mHasLocalTransformation = true;
         mAnimationStartTime = startTime;
+        mStackClip = stackClip;
+    }
+
+    public void setAnimation(Animation anim, int stackClip) {
+        setAnimation(anim, -1, stackClip);
     }
 
     public void setAnimation(Animation anim) {
-        setAnimation(anim, -1);
+        setAnimation(anim, -1, STACK_CLIP_AFTER_ANIM);
     }
 
     public void clearAnimation() {
@@ -252,6 +279,7 @@
             mAnimation = null;
             mKeyguardGoingAwayAnimation = false;
             mKeyguardGoingAwayWithWallpaper = false;
+            mStackClip = STACK_CLIP_BEFORE_ANIM;
         }
     }
 
@@ -397,6 +425,7 @@
         if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this + " anim layer: " + mAnimLayer);
         mHasTransformation = false;
         mHasLocalTransformation = false;
+        mStackClip = STACK_CLIP_BEFORE_ANIM;
         mWin.checkPolicyVisibilityChange();
         mTransformation.clear();
         if (mDrawState == HAS_DRAWN
@@ -994,6 +1023,17 @@
                     if (appTransformation.hasClipRect()) {
                         mClipRect.set(appTransformation.getClipRect());
                         mHasClipRect = true;
+                        // The app transformation clip will be in the coordinate space of the main
+                        // activity window, which the animation correctly assumes will be placed at
+                        // (0,0)+(insets) relative to the containing frame. This isn't necessarily
+                        // true for child windows though which can have an arbitrary frame position
+                        // relative to their containing frame. We need to offset the difference
+                        // between the containing frame as used to calculate the crop and our
+                        // bounds to compensate for this.
+                        if (mWin.isChildWindow() && mWin.layoutInParentFrame()) {
+                            mClipRect.offset( (mWin.mContainingFrame.left - mWin.mFrame.left),
+                                    mWin.mContainingFrame.top - mWin.mFrame.top );
+                        }
                     }
                 }
                 if (screenAnimation) {
@@ -1119,11 +1159,13 @@
         }
     }
 
-    Rect calculateSurfaceWindowCrop() {
+    void calculateSurfaceWindowCrop(Rect clipRect, Rect finalClipRect) {
         final WindowState w = mWin;
         final DisplayContent displayContent = w.getDisplayContent();
         if (displayContent == null) {
-            return null;
+            clipRect.setEmpty();
+            finalClipRect.setEmpty();
+            return;
         }
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Updating crop for window: " + w + ", " + "mLastCrop=" +
@@ -1159,7 +1201,6 @@
         final boolean fullscreen = w.isFrameFullscreen(displayInfo);
         final boolean isFreeformResizing =
                 w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
-        final Rect clipRect = mTmpClipRect;
 
         // We use the clip rect as provided by the tranformation for non-fullscreen windows to
         // avoid premature clipping with the system decor rect.
@@ -1190,7 +1231,8 @@
         // so we need to translate to match the actual surface coordinates.
         clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
 
-        adjustCropToStackBounds(w, clipRect, isFreeformResizing);
+        finalClipRect.setEmpty();
+        adjustCropToStackBounds(w, clipRect, finalClipRect, isFreeformResizing);
         if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Clip rect after stack adjustment=" + clipRect);
 
         w.transformFromScreenToSurfaceSpace(clipRect);
@@ -1199,35 +1241,39 @@
         if (w.hasJustMovedInStack() && mLastClipRect.isEmpty() && !clipRect.isEmpty()) {
             clipRect.setEmpty();
         }
-
-        return clipRect;
     }
 
-    void updateSurfaceWindowCrop(Rect clipRect, boolean recoveringMemory) {
+    void updateSurfaceWindowCrop(Rect clipRect, Rect finalClipRect, boolean recoveringMemory) {
         if (!clipRect.equals(mLastClipRect)) {
             mLastClipRect.set(clipRect);
             mSurfaceController.setCropInTransaction(clipRect, recoveringMemory);
         }
+        if (!finalClipRect.equals(mLastFinalClipRect)) {
+            mLastFinalClipRect.set(finalClipRect);
+            mSurfaceController.setFinalCropInTransaction(finalClipRect);
+        }
     }
 
-    private void adjustCropToStackBounds(WindowState w, Rect clipRect, boolean isFreeformResizing) {
+    private int resolveStackClip() {
+
+        // App animation overrides window animation stack clip mode.
+        if (mAppAnimator != null && mAppAnimator.animation != null) {
+            return mAppAnimator.getStackClip();
+        } else {
+            return mStackClip;
+        }
+    }
+    private void adjustCropToStackBounds(WindowState w, Rect clipRect, Rect finalClipRect,
+            boolean isFreeformResizing) {
         final Task task = w.getTask();
         if (task == null || !task.cropWindowsToStackBounds()) {
             return;
         }
 
-        // We don't apply the stack bounds crop if:
-        // 1. The window is currently animating in freeform mode, otherwise the animating window
-        // will be suddenly (docked) or for whole animation (freeform) cut off.
-        // 2. The window that is being replaced during animation, because it was living in a
-        // different stack. If we suddenly crop it to the new stack bounds, it might get cut off.
-        // We don't want it to happen, so we let it ignore the stack bounds until it gets removed.
-        // The window that will replace it will abide them.
-        // TODO: identify animations where we don't want to apply docked stack crop to the docked
-        //       task. For example, if the app is going from freeform to docked mode, we may not
-        //       want to apply the crop during the animation, since it will make the app appear
-        //       cropped prematurely.
-        if (isAnimating() && (w.mWillReplaceWindow || w.inFreeformWorkspace())) {
+        final int stackClip = resolveStackClip();
+
+        // It's animating and we don't want to clip it to stack bounds during animation - abort.
+        if (isAnimating() && stackClip == STACK_CLIP_NONE) {
             return;
         }
 
@@ -1246,16 +1292,24 @@
         final int frameY = isFreeformResizing ? (int) mSurfaceController.getY() :
                 w.mFrame.top + mWin.mYOffset - w.getAttrs().surfaceInsets.top;
 
+        // If we are animating, we either apply the clip before applying all the animation
+        // transformation or after all the transformation.
+        final boolean useFinalClipRect = isAnimating() && stackClip == STACK_CLIP_AFTER_ANIM;
+
         // We need to do some acrobatics with surface position, because their clip region is
         // relative to the inside of the surface, but the stack bounds aren't.
-        clipRect.left = Math.max(0,
-                Math.max(mTmpStackBounds.left, frameX + clipRect.left) - frameX);
-        clipRect.top = Math.max(0,
-                Math.max(mTmpStackBounds.top, frameY + clipRect.top) - frameY);
-        clipRect.right = Math.max(0,
-                Math.min(mTmpStackBounds.right, frameX + clipRect.right) - frameX);
-        clipRect.bottom = Math.max(0,
-                Math.min(mTmpStackBounds.bottom, frameY + clipRect.bottom) - frameY);
+        if (useFinalClipRect) {
+            finalClipRect.set(mTmpStackBounds);
+        } else {
+            clipRect.left = Math.max(0,
+                    Math.max(mTmpStackBounds.left, frameX + clipRect.left) - frameX);
+            clipRect.top = Math.max(0,
+                    Math.max(mTmpStackBounds.top, frameY + clipRect.top) - frameY);
+            clipRect.right = Math.max(0,
+                    Math.min(mTmpStackBounds.right, frameX + clipRect.right) - frameX);
+            clipRect.bottom = Math.max(0,
+                    Math.min(mTmpStackBounds.bottom, frameY + clipRect.bottom) - frameY);
+        }
     }
 
     void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
@@ -1268,10 +1322,10 @@
         float extraHScale = (float) 1.0;
         float extraVScale = (float) 1.0;
 
-        final Rect crop = calculateSurfaceWindowCrop();
+        calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect);
         if (task != null && task.mStack.getForceScaleToCrop()) {
-            extraHScale = crop.width() / (float)mTmpSize.width();
-            extraVScale = crop.height() / (float)mTmpSize.height();
+            extraHScale = mTmpClipRect.width() / (float)mTmpSize.width();
+            extraVScale = mTmpClipRect.height() / (float)mTmpSize.height();
 
             // In the case of ForceScaleToCrop we scale entire tasks together,
             // and so we need to scale our offsets relative to the task bounds
@@ -1285,12 +1339,13 @@
             // Since we are scaled to fit in our previously desired crop, we can now
             // expose the whole window in buffer space, and not risk extending
             // past where the system would have cropped us
-            crop.set(0, 0, mTmpSize.width(), mTmpSize.height());
-            updateSurfaceWindowCrop(crop, recoveringMemory);
+            mTmpClipRect.set(0, 0, mTmpSize.width(), mTmpSize.height());
+            mTmpFinalClipRect.setEmpty();
+            updateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect, recoveringMemory);
         } else {
             mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top,
                     recoveringMemory);
-            updateSurfaceWindowCrop(crop, recoveringMemory);
+            updateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect, recoveringMemory);
         }
 
 
@@ -1447,7 +1502,8 @@
             SurfaceControl.openTransaction();
             mSurfaceController.setPositionInTransaction(mWin.mFrame.left + left,
                     mWin.mFrame.top + top, false);
-            updateSurfaceWindowCrop(calculateSurfaceWindowCrop(), false);
+            calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect);
+            updateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect, false);
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error positioning surface of " + mWin
                     + " pos=(" + left + "," + top + ")", e);
@@ -1710,6 +1766,7 @@
                     pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
                     pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
                     pw.print(" mAnimation="); pw.println(mAnimation);
+                    pw.print(" mStackClip="); pw.println(mStackClip);
         }
         if (mHasTransformation || mHasLocalTransformation) {
             pw.print(prefix); pw.print("XForm: has=");
@@ -1729,6 +1786,9 @@
             if (mHasClipRect) {
                 pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
             }
+            if (!mLastFinalClipRect.isEmpty()) {
+                pw.print(" mLastFinalClipRect="); mLastFinalClipRect.printShortString(pw);
+            }
             pw.println();
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index be3ad3b..8799c61 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -189,6 +189,16 @@
         }
     }
 
+    void setFinalCropInTransaction(Rect clipRect) {
+        if (SHOW_TRANSACTIONS) logSurface(
+                "FINAL CROP " + clipRect.toShortString(), null);
+        try {
+            mSurfaceControl.setFinalCrop(clipRect);
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Error disconnecting surface in: " + this, e);
+        }
+    }
+
     void setLayer(int layer) {
         if (mSurfaceControl != null) {
             SurfaceControl.openTransaction();
@@ -460,6 +470,7 @@
         private final PointF mPosition = new PointF();
         private final Point mSize = new Point();
         private final Rect mWindowCrop = new Rect();
+        private final Rect mFinalCrop = new Rect();
         private boolean mShown = false;
         private int mLayerStack;
         private boolean mIsOpaque;
@@ -545,6 +556,19 @@
         }
 
         @Override
+        public void setFinalCrop(Rect crop) {
+            if (crop != null) {
+                if (!crop.equals(mFinalCrop)) {
+                    if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop("
+                            + crop.toShortString() + "): OLD:" + this + ". Called by "
+                            + Debug.getCallers(3));
+                    mFinalCrop.set(crop);
+                }
+            }
+            super.setFinalCrop(crop);
+        }
+
+        @Override
         public void setLayerStack(int layerStack) {
             if (layerStack != mLayerStack) {
                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
@@ -655,6 +679,7 @@
                             pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
                             pw.println(s.mSize.y);
                     pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
+                    pw.print("    mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println();
                     pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
                             pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
                             pw.print(", "); pw.print(s.mDtdy); pw.println(")");
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 5ad771f..3b0081d 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -9,6 +9,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
@@ -18,6 +19,7 @@
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
@@ -30,13 +32,21 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerService.H.*;
-import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
-import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
+import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
+import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
+import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
+import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
+import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
+import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
+import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
+import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
+import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
+import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
@@ -687,7 +697,11 @@
                             w.getTask().mStack.isAdjustedForMinimizedDockedStack();
                     if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
                             && !w.isDragResizing() && !adjustedForMinimizedDockedStack
-                            && (task == null || !w.getTask().mStack.getFreezeMovementAnimations())) {
+                            && (task == null || !w.getTask().mStack.getFreezeMovementAnimations())
+                            && !w.mWinAnimator.mLastHidden) {
+                        winAnimator.setMoveAnimation(left, top);
+                    } else if (w.mAttrs.type  == TYPE_DOCK_DIVIDER &&
+                            displayContent.getDockedDividerController().isAdjustingForIme()) {
                         winAnimator.setMoveAnimation(left, top);
                     }
 
@@ -701,11 +715,11 @@
                         w.mClient.moved(left, top);
                     } catch (RemoteException e) {
                     }
+                    w.mMovedByResize = false;
                 }
 
                 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
                 w.mContentChanged = false;
-                w.mMovedByResize = false;
 
                 // Moved from updateWindowsAndWallpaperLocked().
                 if (w.mHasSurface) {
@@ -805,6 +819,8 @@
                 mService.updateResizingWindows(w);
             }
 
+            displayContent.getDockedDividerController().setAdjustingForIme(false);
+
             mService.mDisplayManagerInternal.setDisplayProperties(displayId,
                     mDisplayHasContent,
                     mPreferredRefreshRate,
@@ -1218,6 +1234,10 @@
             if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
                 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
             }
+            if (mService.mAppTransition.getAppTransition()
+                    == AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS) {
+                appAnimator.startProlongAnimation(PROLONG_ANIMATION_AT_START);
+            }
         }
         return topOpeningApp;
     }
@@ -1556,12 +1576,13 @@
                 WindowState win = appToken.findMainWindow();
                 Rect appRect = win != null ? win.getContentFrameLw() :
                         new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+                Rect insets = win != null ? win.mContentInsets : null;
                 // For the new aspect-scaled transition, we want it to always show
                 // above the animating opening/closing window, and we want to
                 // synchronize its thumbnail surface with the surface for the
                 // open/close animation (only on the way down)
                 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
-                        thumbnailHeader, taskId);
+                        insets, thumbnailHeader, taskId, mService.mCurConfiguration.orientation);
                 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
                 openingAppAnimator.deferThumbnailDestruction =
                         !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
@@ -1576,8 +1597,6 @@
             openingAppAnimator.thumbnailLayer = openingLayer;
             openingAppAnimator.thumbnailAnimation = anim;
             mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
-            openingAppAnimator.thumbnailX = mTmpStartRect.left;
-            openingAppAnimator.thumbnailY = mTmpStartRect.top;
         } catch (Surface.OutOfResourcesException e) {
             Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
                     + dirty.width() + " h=" + dirty.height(), e);
diff --git a/services/core/java/com/android/server/wm/animation/CurvedTranslateAnimation.java b/services/core/java/com/android/server/wm/animation/CurvedTranslateAnimation.java
new file mode 100644
index 0000000..33ac2ff
--- /dev/null
+++ b/services/core/java/com/android/server/wm/animation/CurvedTranslateAnimation.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm.animation;
+
+import android.animation.KeyframeSet;
+import android.animation.PathKeyframes;
+import android.graphics.Path;
+import android.graphics.PointF;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+/**
+ * Translate animation which follows a curved path.
+ */
+public class CurvedTranslateAnimation extends Animation {
+
+    private final PathKeyframes mKeyframes;
+
+    public CurvedTranslateAnimation(Path path) {
+        mKeyframes = KeyframeSet.ofPath(path);
+    }
+
+    @Override
+    protected void applyTransformation(float interpolatedTime, Transformation t) {
+        PointF location = (PointF) mKeyframes.getValue(interpolatedTime);
+        t.getMatrix().setTranslate(location.x, location.y);
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c362c9c..d8b856b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4868,10 +4868,24 @@
         // we start using it for different purposes.
         ensureCallerPackage(callerPackage);
 
+        final ApplicationInfo ai;
+        try {
+            ai = mContext.getPackageManager().getApplicationInfo(callerPackage, 0);
+        } catch (NameNotFoundException e) {
+            throw new SecurityException(e);
+        }
+
+        boolean legacyApp = false;
+        if (ai.targetSdkVersion <= Build.VERSION_CODES.M) {
+            legacyApp = true;
+        } else if ("com.google.android.apps.enterprise.dmagent".equals(ai.packageName)
+                && ai.versionCode == 697) {
+            // TODO: remove this once a new prebuilt is dropped
+            legacyApp = true;
+        }
+
         final int rawStatus = getEncryptionStatus();
-        if ((rawStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER)
-                && (callerPackage != null)
-                && (getTargetSdk(callerPackage, userHandle) <= VERSION_CODES.M)) {
+        if ((rawStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER) && legacyApp) {
             return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
         }
         return rawStatus;
@@ -7513,7 +7527,9 @@
     /**
      * Sets which packages may enter lock task mode.
      *
-     * This function can only be called by the device owner.
+     * <p>This function can only be called by the device owner or alternatively by the profile owner
+     * in case the user is affiliated.
+     *
      * @param packages The list of packages allowed to enter lock task mode.
      */
     @Override
@@ -7521,10 +7537,17 @@
             throws SecurityException {
         Preconditions.checkNotNull(who, "ComponentName is null");
         synchronized (this) {
-            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
-
-            int userHandle = mInjector.binderGetCallingUserHandle().getIdentifier();
-            setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages)));
+            ActiveAdmin deviceOwner = getActiveAdminWithPolicyForUidLocked(
+                who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, mInjector.binderGetCallingUid());
+            ActiveAdmin profileOwner = getActiveAdminWithPolicyForUidLocked(
+                who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid());
+            if (deviceOwner != null || (profileOwner != null && isAffiliatedUser())) {
+                int userHandle = mInjector.userHandleGetCallingUserId();
+                setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages)));
+            } else {
+                throw new SecurityException("Admin " + who +
+                    " is neither the device owner or affiliated user's profile owner.");
+            }
         }
     }
 
diff --git a/services/net/java/android/net/apf/ApfCapabilities.java b/services/net/java/android/net/apf/ApfCapabilities.java
new file mode 100644
index 0000000..f169411
--- /dev/null
+++ b/services/net/java/android/net/apf/ApfCapabilities.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.apf;
+
+/**
+ * APF program support capabilities.
+ *
+ * @hide
+ */
+public class ApfCapabilities {
+    /**
+     * Version of APF instruction set supported for packet filtering. 0 indicates no support for
+     * packet filtering using APF programs.
+     */
+    public final int apfVersionSupported;
+
+    /**
+     * Maximum size of APF program allowed.
+     */
+    public final int maximumApfProgramSize;
+
+    /**
+     * Format of packets passed to APF filter. Should be one of ARPHRD_*
+     */
+    public final int apfPacketFormat;
+
+    ApfCapabilities(int apfVersionSupported, int maximumApfProgramSize, int apfPacketFormat) {
+        this.apfVersionSupported = apfVersionSupported;
+        this.maximumApfProgramSize = maximumApfProgramSize;
+        this.apfPacketFormat = apfPacketFormat;
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/connectivity/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
similarity index 65%
rename from services/core/java/com/android/server/connectivity/ApfFilter.java
rename to services/net/java/android/net/apf/ApfFilter.java
index 824db65..ebbf991 100644
--- a/services/core/java/com/android/server/connectivity/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.connectivity;
+package android.net.apf;
 
 import static android.system.OsConstants.*;
 
@@ -22,15 +22,16 @@
 import android.net.apf.ApfGenerator;
 import android.net.apf.ApfGenerator.IllegalInstructionException;
 import android.net.apf.ApfGenerator.Register;
+import android.net.ip.IpManager;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.PacketSocketAddress;
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.ConnectivityService;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -52,6 +53,17 @@
  * listens for IPv6 ICMPv6 router advertisements (RAs) and generates APF programs to
  * filter out redundant duplicate ones.
  *
+ * Threading model:
+ * A collection of RAs we've received is kept in mRas. Generating APF programs uses mRas to
+ * know what RAs to filter for, thus generating APF programs is dependent on mRas.
+ * mRas can be accessed by multiple threads:
+ * - ReceiveThread, which listens for RAs and adds them to mRas, and generates APF programs.
+ * - callers of:
+ *    - setMulticastFilter(), which can cause an APF program to be generated.
+ *    - dump(), which dumps mRas among other things.
+ *    - shutdown(), which clears mRas.
+ * So access to mRas is synchronized.
+ *
  * @hide
  */
 public class ApfFilter {
@@ -93,23 +105,62 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
-    private final ConnectivityService mConnectivityService;
-    private final NetworkAgentInfo mNai;
-    private ReceiveThread mReceiveThread;
-    private String mIfaceName;
-    private long mUniqueCounter;
+    private static final int ETH_HEADER_LEN = 14;
+    private static final int ETH_ETHERTYPE_OFFSET = 12;
+    private static final byte[] ETH_BROADCAST_MAC_ADDRESS = new byte[]{
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
+    // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN.
+    private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6;
+    // Endianness is not an issue for this constant because the APF interpreter always operates in
+    // network byte order.
+    private static final int IPV4_FRAGMENT_OFFSET_MASK = 0x1fff;
+    private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
+    private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
 
-    private ApfFilter(ConnectivityService connectivityService, NetworkAgentInfo nai) {
-        mConnectivityService = connectivityService;
-        mNai = nai;
+    private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
+    private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
+    private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
+    private static final int IPV6_HEADER_LEN = 40;
+    // The IPv6 all nodes address ff02::1
+    private static final byte[] IPV6_ALL_NODES_ADDRESS =
+            new byte[]{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+    private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
+    private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
+
+    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
+    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
+    private static final int UDP_HEADER_LEN = 8;
+
+    private static final int DHCP_CLIENT_PORT = 68;
+    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
+    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
+
+    private final ApfCapabilities mApfCapabilities;
+    private final IpManager.Callback mIpManagerCallback;
+    private final NetworkInterface mNetworkInterface;
+    private byte[] mHardwareAddress;
+    private ReceiveThread mReceiveThread;
+    @GuardedBy("this")
+    private long mUniqueCounter;
+    @GuardedBy("this")
+    private boolean mMulticastFilter;
+
+    private ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface,
+            IpManager.Callback ipManagerCallback) {
+        mApfCapabilities = apfCapabilities;
+        mIpManagerCallback = ipManagerCallback;
+        mNetworkInterface = networkInterface;
+
         maybeStartFilter();
     }
 
     private void log(String s) {
-        Log.d(TAG, "(" + mNai.network.netId + "): " + s);
+        Log.d(TAG, "(" + mNetworkInterface.getName() + "): " + s);
     }
 
-    private long getUniqueNumber() {
+    @GuardedBy("this")
+    private long getUniqueNumberLocked() {
         return mUniqueCounter++;
     }
 
@@ -118,37 +169,26 @@
      * filters to ignore useless RAs.
      */
     private void maybeStartFilter() {
-        mIfaceName = mNai.linkProperties.getInterfaceName();
-        if (mIfaceName == null) return;
         FileDescriptor socket;
         try {
+            mHardwareAddress = mNetworkInterface.getHardwareAddress();
+            synchronized(this) {
+                // Install basic filters
+                installNewProgramLocked();
+            }
             socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
             PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IPV6,
-                    NetworkInterface.getByName(mIfaceName).getIndex());
+                    mNetworkInterface.getIndex());
             Os.bind(socket, addr);
-            NetworkUtils.attachRaFilter(socket, mNai.networkMisc.apfPacketFormat);
+            NetworkUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
         } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error filtering raw socket", e);
+            Log.e(TAG, "Error starting filter", e);
             return;
         }
         mReceiveThread = new ReceiveThread(socket);
         mReceiveThread.start();
     }
 
-    /**
-     * mNai's LinkProperties may have changed, take appropriate action.
-     */
-    public void updateFilter() {
-        // If we're not listening for RAs, try starting.
-        if (mReceiveThread == null) {
-            maybeStartFilter();
-        // If interface name has changed, restart.
-        } else if (!mIfaceName.equals(mNai.linkProperties.getInterfaceName())) {
-            shutdown();
-            maybeStartFilter();
-        }
-    }
-
     // Returns seconds since Unix Epoch.
     private static long curTime() {
         return System.currentTimeMillis() / 1000L;
@@ -156,12 +196,6 @@
 
     // A class to hold information about an RA.
     private class Ra {
-        private static final int ETH_HEADER_LEN = 14;
-
-        private static final int IPV6_HEADER_LEN = 40;
-        private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
-        private static final int IPV6_DST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
-
         // From RFC4861:
         private static final int ICMP6_RA_HEADER_LEN = 16;
         private static final int ICMP6_RA_CHECKSUM_OFFSET =
@@ -250,7 +284,7 @@
                 StringBuffer sb = new StringBuffer();
                 sb.append(String.format("RA %s -> %s %d ",
                         IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
-                        IPv6AddresstoString(IPV6_DST_ADDR_OFFSET),
+                        IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
                         uint16(mPacket.getShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET))));
                 for (int i: mPrefixOptionOffsets) {
                     String prefix = IPv6AddresstoString(i + 16);
@@ -302,7 +336,7 @@
                     ICMP6_RA_ROUTER_LIFETIME_OFFSET,
                     ICMP6_RA_ROUTER_LIFETIME_LEN);
 
-            // Parse ICMP6 options
+            // Parse ICMPv6 options
             mPrefixOptionOffsets = new ArrayList<>();
             mPacket.position(ICMP6_RA_OPTION_OFFSET);
             while (mPacket.hasRemaining()) {
@@ -394,13 +428,16 @@
         }
 
         boolean isExpired() {
-            return currentLifetime() < 0;
+            // TODO: We may want to handle 0 lifetime RAs differently, if they are common. We'll
+            // have to calculte the filter lifetime specially as a fraction of 0 is still 0.
+            return currentLifetime() <= 0;
         }
 
         // Append a filter for this RA to {@code gen}. Jump to DROP_LABEL if it should be dropped.
         // Jump to the next filter if packet doesn't match this RA.
-        long generateFilter(ApfGenerator gen) throws IllegalInstructionException {
-            String nextFilterLabel = "Ra" + getUniqueNumber();
+        @GuardedBy("ApfFilter.this")
+        long generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+            String nextFilterLabel = "Ra" + getUniqueNumberLocked();
             // Skip if packet is not the right size
             gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
             gen.addJumpIfR0NotEquals(mPacket.limit(), nextFilterLabel);
@@ -447,6 +484,8 @@
 
     // Maximum number of RAs to filter for.
     private static final int MAX_RAS = 10;
+
+    @GuardedBy("this")
     private ArrayList<Ra> mRas = new ArrayList<Ra>();
 
     // There is always some marginal benefit to updating the installed APF program when an RA is
@@ -460,42 +499,167 @@
     private static final int FRACTION_OF_LIFETIME_TO_FILTER = 6;
 
     // When did we last install a filter program? In seconds since Unix Epoch.
+    @GuardedBy("this")
     private long mLastTimeInstalledProgram;
     // How long should the last installed filter program live for? In seconds.
+    @GuardedBy("this")
     private long mLastInstalledProgramMinLifetime;
 
-    // For debugging only. The length in bytes of the last program.
+    // For debugging only. The last program installed.
+    @GuardedBy("this")
     private byte[] mLastInstalledProgram;
 
-    private void installNewProgram() {
-        if (mRas.size() == 0) return;
+    /**
+     * Generate filter code to process IPv4 packets. Execution of this code ends in either the
+     * DROP_LABEL or PASS_LABEL and does not fall off the end.
+     * Preconditions:
+     *  - Packet being filtered is IPv4
+     *  - R1 is initialized to 0
+     */
+    @GuardedBy("this")
+    private void generateIPv4FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+        // Here's a basic summary of what the IPv4 filter program does:
+        //
+        // if it's multicast and we're dropping multicast:
+        //   drop
+        // if it's not broadcast:
+        //   pass
+        // if it's not DHCP destined to our MAC:
+        //   drop
+        // pass
+
+        if (mMulticastFilter) {
+            // Check for multicast destination address range
+            gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
+            gen.addAnd(0xf0);
+            gen.addJumpIfR0Equals(0xe0, gen.DROP_LABEL);
+        }
+
+        // Drop all broadcasts besides DHCP addressed to us
+        // If not a broadcast packet, pass
+        // NOTE: Relies on R1 being initialized to 0 which is the offset of the ethernet
+        //       destination MAC address
+        gen.addJumpIfBytesNotEqual(Register.R1, ETH_BROADCAST_MAC_ADDRESS, gen.PASS_LABEL);
+        // If not UDP, drop
+        gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
+        gen.addJumpIfR0NotEquals(IPPROTO_UDP, gen.DROP_LABEL);
+        // If fragment, drop. This matches the BPF filter installed by the DHCP client.
+        gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET);
+        gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, gen.DROP_LABEL);
+        // If not to DHCP client port, drop
+        gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
+        gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET);
+        gen.addJumpIfR0NotEquals(DHCP_CLIENT_PORT, gen.DROP_LABEL);
+        // If not DHCP to our MAC address, drop
+        gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET);
+        // NOTE: Relies on R1 containing IPv4 header offset.
+        gen.addAddR1();
+        gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, gen.DROP_LABEL);
+
+        // Otherwise, pass
+        gen.addJump(gen.PASS_LABEL);
+    }
+
+
+    /**
+     * Generate filter code to process IPv6 packets. Execution of this code ends in either the
+     * DROP_LABEL or PASS_LABEL, or falls off the end for ICMPv6 packets.
+     * Preconditions:
+     *  - Packet being filtered is IPv6
+     *  - R1 is initialized to 0
+     */
+    @GuardedBy("this")
+    private void generateIPv6FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
+        // Here's a basic summary of what the IPv6 filter program does:
+        //
+        // if it's not ICMPv6:
+        //   pass
+        // if it's ICMPv6 NA to ff02::1:
+        //   drop
+
+        // If not ICMPv6, pass
+        gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
+        // TODO: Drop multicast if the multicast filter is enabled.
+        gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, gen.PASS_LABEL);
+        // Add unsolicited multicast neighbor announcements filter
+        String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
+        // If not neighbor announcements, skip unsolicited multicast NA filter
+        gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
+        gen.addJumpIfR0NotEquals(ICMP6_NEIGHBOR_ANNOUNCEMENT, skipUnsolicitedMulticastNALabel);
+        // If to ff02::1, drop
+        // TODO: Drop only if they don't contain the address of on-link neighbours.
+        gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
+        gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
+                skipUnsolicitedMulticastNALabel);
+        gen.addJump(gen.DROP_LABEL);
+        gen.defineLabel(skipUnsolicitedMulticastNALabel);
+    }
+
+    /**
+     * Begin generating an APF program to:
+     * <ul>
+     * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC,
+     * <li>Drop IPv4 multicast packets, if mMulticastFilter,
+     * <li>Pass all other IPv4 packets,
+     * <li>Pass all non-ICMPv6 IPv6 packets,
+     * <li>Pass all non-IPv4 and non-IPv6 packets,
+     * <li>Drop IPv6 ICMPv6 NAs to ff02::1.
+     * <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows
+     *     insertion of RA filters here, or if there aren't any, just passes the packets.
+     * </ul>
+     */
+    @GuardedBy("this")
+    private ApfGenerator beginProgramLocked() throws IllegalInstructionException {
+        ApfGenerator gen = new ApfGenerator();
+        // This is guaranteed to return true because of the check in maybeCreate.
+        gen.setApfVersion(mApfCapabilities.apfVersionSupported);
+
+        // Here's a basic summary of what the initial program does:
+        //
+        // if it's IPv4:
+        //   insert IPv4 filter to drop or pass these appropriately
+        // if it's not IPv6:
+        //   pass
+        // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets
+
+        // Add IPv4 filters:
+        String skipIPv4FiltersLabel = "skipIPv4Filters";
+        // If not IPv4, skip IPv4 filters
+        gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET);
+        gen.addJumpIfR0NotEquals(ETH_P_IP, skipIPv4FiltersLabel);
+        // NOTE: Relies on R1 being initialized to 0.
+        generateIPv4FilterLocked(gen);
+        gen.defineLabel(skipIPv4FiltersLabel);
+
+        // Add IPv6 filters:
+        // If not IPv6, pass
+        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
+        // execute the IPv4 filter, since that filter does not fall through, but either drops or
+        // passes.
+        gen.addJumpIfR0NotEquals(ETH_P_IPV6, gen.PASS_LABEL);
+        generateIPv6FilterLocked(gen);
+        return gen;
+    }
+
+    @GuardedBy("this")
+    private void installNewProgramLocked() {
+        purgeExpiredRasLocked();
         final byte[] program;
         long programMinLifetime = Long.MAX_VALUE;
         try {
-            ApfGenerator gen = new ApfGenerator();
-            // This is guaranteed to return true because of the check in maybeInstall.
-            gen.setApfVersion(mNai.networkMisc.apfVersionSupported);
             // Step 1: Determine how many RA filters we can fit in the program.
-            int ras = 0;
+            ApfGenerator gen = beginProgramLocked();
+            ArrayList<Ra> rasToFilter = new ArrayList<Ra>();
             for (Ra ra : mRas) {
-                if (ra.isExpired()) continue;
-                ra.generateFilter(gen);
-                if (gen.programLengthOverEstimate() > mNai.networkMisc.maximumApfProgramSize) {
-                    // We went too far.  Use prior number of RAs in "ras".
-                    break;
-                } else {
-                    // Yay! this RA filter fits, increment "ras".
-                    ras++;
-                }
+                ra.generateFilterLocked(gen);
+                // Stop if we get too big.
+                if (gen.programLengthOverEstimate() > mApfCapabilities.maximumApfProgramSize) break;
+                rasToFilter.add(ra);
             }
-            // Step 2: Generate RA filters
-            gen = new ApfGenerator();
-            // This is guaranteed to return true because of the check in maybeInstall.
-            gen.setApfVersion(mNai.networkMisc.apfVersionSupported);
-            for (Ra ra : mRas) {
-                if (ras-- == 0) break;
-                if (ra.isExpired()) continue;
-                programMinLifetime = Math.min(programMinLifetime, ra.generateFilter(gen));
+            // Step 2: Actually generate the program
+            gen = beginProgramLocked();
+            for (Ra ra : rasToFilter) {
+                programMinLifetime = Math.min(programMinLifetime, ra.generateFilterLocked(gen));
             }
             // Execution will reach the end of the program if no filters match, which will pass the
             // packet to the AP.
@@ -509,19 +673,18 @@
         mLastInstalledProgram = program;
         if (VDBG) {
             hexDump("Installing filter: ", program, program.length);
-        } else {
-            Log.d(TAG, "Installing filter length=" + program.length);
         }
-        mConnectivityService.pushApfProgramToNetwork(mNai, program);
+        mIpManagerCallback.installPacketFilter(program);
     }
 
     // Install a new filter program if the last installed one will die soon.
-    private void maybeInstallNewProgram() {
+    @GuardedBy("this")
+    private void maybeInstallNewProgramLocked() {
         if (mRas.size() == 0) return;
         // If the current program doesn't expire for a while, don't bother updating.
         long expiry = mLastTimeInstalledProgram + mLastInstalledProgramMinLifetime;
         if (expiry < curTime() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING) {
-            installNewProgram();
+            installNewProgramLocked();
         }
     }
 
@@ -529,7 +692,19 @@
         log(msg + HexDump.toHexString(packet, 0, length, false /* lowercase */));
     }
 
-    private void processRa(byte[] packet, int length) {
+    @GuardedBy("this")
+    private void purgeExpiredRasLocked() {
+        for (int i = 0; i < mRas.size();) {
+            if (mRas.get(i).isExpired()) {
+                log("Expiring " + mRas.get(i));
+                mRas.remove(i);
+            } else {
+                i++;
+            }
+        }
+    }
+
+    private synchronized void processRa(byte[] packet, int length) {
         if (VDBG) hexDump("Read packet = ", packet, length);
 
         // Have we seen this RA before?
@@ -551,66 +726,70 @@
                 // Swap to front of array.
                 mRas.add(0, mRas.remove(i));
 
-                maybeInstallNewProgram();
+                maybeInstallNewProgramLocked();
                 return;
             }
         }
-        // Purge expired RAs.
-        for (int i = 0; i < mRas.size();) {
-            if (mRas.get(i).isExpired()) {
-                log("Expired RA " + mRas.get(i));
-                mRas.remove(i);
-            } else {
-                i++;
-            }
-        }
+        purgeExpiredRasLocked();
         // TODO: figure out how to proceed when we've received more then MAX_RAS RAs.
         if (mRas.size() >= MAX_RAS) return;
+        final Ra ra;
         try {
-            Ra ra = new Ra(packet, length);
-            log("Adding " + ra);
-            mRas.add(ra);
+            ra = new Ra(packet, length);
         } catch (Exception e) {
             Log.e(TAG, "Error parsing RA: " + e);
             return;
         }
-        installNewProgram();
+        // Ignore 0 lifetime RAs.
+        if (ra.isExpired()) return;
+        log("Adding " + ra);
+        mRas.add(ra);
+        installNewProgramLocked();
     }
 
     /**
-     * Install an {@link ApfFilter} on {@code nai} if {@code nai} supports packet
+     * Create an {@link ApfFilter} if {@code apfCapabilities} indicates support for packet
      * filtering using APF programs.
      */
-    public static void maybeInstall(ConnectivityService connectivityService, NetworkAgentInfo nai) {
-        if (nai.networkMisc == null) return;
-        if (nai.networkMisc.apfVersionSupported == 0) return;
-        if (nai.networkMisc.maximumApfProgramSize < 512) {
-            Log.e(TAG, "Unacceptably small APF limit: " + nai.networkMisc.maximumApfProgramSize);
-            return;
+    public static ApfFilter maybeCreate(ApfCapabilities apfCapabilities,
+            NetworkInterface networkInterface, IpManager.Callback ipManagerCallback) {
+        if (apfCapabilities == null || networkInterface == null) return null;
+        if (apfCapabilities.apfVersionSupported == 0) return null;
+        if (apfCapabilities.maximumApfProgramSize < 512) {
+            Log.e(TAG, "Unacceptably small APF limit: " + apfCapabilities.maximumApfProgramSize);
+            return null;
         }
         // For now only support generating programs for Ethernet frames. If this restriction is
         // lifted:
         //   1. the program generator will need its offsets adjusted.
         //   2. the packet filter attached to our packet socket will need its offset adjusted.
-        if (nai.networkMisc.apfPacketFormat != ARPHRD_ETHER) return;
-        if (!new ApfGenerator().setApfVersion(nai.networkMisc.apfVersionSupported)) {
-            Log.e(TAG, "Unsupported APF version: " + nai.networkMisc.apfVersionSupported);
-            return;
+        if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null;
+        if (!new ApfGenerator().setApfVersion(apfCapabilities.apfVersionSupported)) {
+            Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported);
+            return null;
         }
-        nai.apfFilter = new ApfFilter(connectivityService, nai);
+        return new ApfFilter(apfCapabilities, networkInterface, ipManagerCallback);
     }
 
-    public void shutdown() {
+    public synchronized void shutdown() {
         if (mReceiveThread != null) {
             log("shutting down");
             mReceiveThread.halt();  // Also closes socket.
             mReceiveThread = null;
         }
+        mRas.clear();
     }
 
-    public void dump(IndentingPrintWriter pw) {
-        pw.println("APF version: " + mNai.networkMisc.apfVersionSupported);
-        pw.println("Max program size: " + mNai.networkMisc.maximumApfProgramSize);
+    public synchronized void setMulticastFilter(boolean enabled) {
+        if (mMulticastFilter != enabled) {
+            mMulticastFilter = enabled;
+            installNewProgramLocked();
+        }
+    }
+
+    public synchronized void dump(IndentingPrintWriter pw) {
+        pw.println("APF version: " + mApfCapabilities.apfVersionSupported);
+        pw.println("Max program size: " + mApfCapabilities.maximumApfProgramSize);
         pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
         if (mLastTimeInstalledProgram == 0) {
             pw.println("No program installed.");
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index e2562cd..406dd56 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -30,6 +30,8 @@
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
+import android.net.metrics.IpConnectivityEvent;
+import android.net.metrics.DhcpClientEvent;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Message;
@@ -136,7 +138,7 @@
             MessageUtils.findMessageNames(sMessageClasses);
 
     // DHCP parameters that we request.
-    private static final byte[] REQUESTED_PARAMS = new byte[] {
+    /* package */ static final byte[] REQUESTED_PARAMS = new byte[] {
         DHCP_SUBNET_MASK,
         DHCP_ROUTER,
         DHCP_DNS_SERVER,
@@ -146,6 +148,7 @@
         DHCP_LEASE_TIME,
         DHCP_RENEWAL_TIME,
         DHCP_REBINDING_TIME,
+        DHCP_VENDOR_INFO,
     };
 
     // DHCP flag that means "yes, we support unicast."
@@ -355,11 +358,15 @@
                     if (!stopped) {
                         Log.e(TAG, "Read error", e);
                     }
+                    DhcpClientEvent.logEvent(IpConnectivityEvent.IPCE_DHCP_RECV_ERROR,
+                            mIfaceName, e.getMessage());
                 } catch (DhcpPacket.ParseException e) {
                     Log.e(TAG, "Can't parse packet: " + e.getMessage());
                     if (PACKET_DBG) {
                         Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
                     }
+                    DhcpClientEvent.logEvent(IpConnectivityEvent.IPCE_DHCP_PARSE_ERROR, mIfaceName,
+                            e.getMessage());
                 }
             }
             if (DBG) Log.d(TAG, "Receive thread stopped");
@@ -456,7 +463,9 @@
 
     abstract class LoggingState extends State {
         public void enter() {
-            if (STATE_DBG) Log.d(TAG, "Entering state " + getName());
+            String msg = "Entering state " + getName();
+            if (STATE_DBG) Log.d(TAG, msg);
+            DhcpClientEvent.logEvent(IpConnectivityEvent.IPCE_DHCP_STATE_CHANGE, mIfaceName, msg);
         }
 
         private String messageName(int what) {
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index c7c5015..66c7909 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -19,6 +19,8 @@
 import com.android.internal.util.MessageUtils;
 
 import android.content.Context;
+import android.net.apf.ApfCapabilities;
+import android.net.apf.ApfFilter;
 import android.net.DhcpResults;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
@@ -38,10 +40,12 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.server.net.NetlinkTracker;
 
+import java.io.PrintWriter;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
@@ -108,6 +112,9 @@
 
         // Called when the IpManager state machine terminates.
         public void onQuit() {}
+
+        // Install an APF program to filter incoming packets.
+        public void installPacketFilter(byte[] filter) {}
     }
 
     public static class WaitForProvisioningCallback extends Callback {
@@ -179,6 +186,11 @@
                 return this;
             }
 
+            public Builder withApfCapabilities(ApfCapabilities apfCapabilities) {
+                mConfig.mApfCapabilities = apfCapabilities;
+                return this;
+            }
+
             public ProvisioningConfiguration build() {
                 return new ProvisioningConfiguration(mConfig);
             }
@@ -187,6 +199,7 @@
         /* package */ boolean mUsingIpReachabilityMonitor = true;
         /* package */ boolean mRequestedPreDhcpAction;
         /* package */ StaticIpConfiguration mStaticIpConfig;
+        /* package */ ApfCapabilities mApfCapabilities;
 
         public ProvisioningConfiguration() {}
 
@@ -194,6 +207,7 @@
             mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
             mRequestedPreDhcpAction = other.mRequestedPreDhcpAction;
             mStaticIpConfig = other.mStaticIpConfig;
+            mApfCapabilities = other.mApfCapabilities;
         }
     }
 
@@ -229,7 +243,7 @@
     private final INetworkManagementService mNwService;
     private final NetlinkTracker mNetlinkTracker;
 
-    private int mInterfaceIndex;
+    private NetworkInterface mNetworkInterface;
 
     /**
      * Non-final member variables accessed only from within our StateMachine.
@@ -240,6 +254,7 @@
     private DhcpResults mDhcpResults;
     private String mTcpBufferSizes;
     private ProxyInfo mHttpProxy;
+    private ApfFilter mApfFilter;
 
     /**
      * Member variables accessed both from within the StateMachine thread
@@ -325,7 +340,7 @@
     }
 
     public void startProvisioning(ProvisioningConfiguration req) {
-        getInterfaceIndex();
+        getNetworkInterface();
         sendMessage(CMD_START, new ProvisioningConfiguration(req));
     }
 
@@ -378,6 +393,19 @@
         }
     }
 
+    public void dumpApf(PrintWriter writer) {
+        writer.println("--------------------------------------------------------------------");
+        writer.println("APF dump:");
+        // Thread-unsafe access to mApfFilter but just used for debugging.
+        ApfFilter apfFilter = mApfFilter;
+        if (apfFilter != null) {
+            apfFilter.dump(new IndentingPrintWriter(writer, "  "));
+        } else {
+            writer.println("No apf support");
+        }
+        writer.println("--------------------------------------------------------------------");
+    }
+
 
     /**
      * Internals.
@@ -392,7 +420,7 @@
     protected String getLogRecString(Message msg) {
         final String logLine = String.format(
                 "iface{%s/%d} arg1{%d} arg2{%d} obj{%s}",
-                mInterfaceName, mInterfaceIndex,
+                mInterfaceName, mNetworkInterface == null ? -1 : mNetworkInterface.getIndex(),
                 msg.arg1, msg.arg2, Objects.toString(msg.obj));
         if (VDBG) {
             Log.d(mTag, getWhatToString(msg.what) + " " + logLine);
@@ -400,12 +428,12 @@
         return logLine;
     }
 
-    private void getInterfaceIndex() {
+    private void getNetworkInterface() {
         try {
-            mInterfaceIndex = NetworkInterface.getByName(mInterfaceName).getIndex();
+            mNetworkInterface = NetworkInterface.getByName(mInterfaceName);
         } catch (SocketException | NullPointerException e) {
             // TODO: throw new IllegalStateException.
-            Log.e(mTag, "ALERT: Failed to get interface index: ", e);
+            Log.e(mTag, "ALERT: Failed to get interface object: ", e);
         }
     }
 
@@ -732,6 +760,8 @@
     class StartedState extends State {
         @Override
         public void enter() {
+            mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface,
+                    mCallback);
             // Set privacy extensions.
             try {
                 mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
@@ -788,6 +818,11 @@
                 mDhcpClient.doQuit();
             }
 
+            if (mApfFilter != null) {
+                mApfFilter.shutdown();
+                mApfFilter = null;
+            }
+
             resetLinkProperties();
         }
 
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index 5b4fd50..af3175a 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -24,6 +24,8 @@
 import android.net.LinkProperties.ProvisioningChange;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
+import android.net.metrics.IpReachabilityMonitorMessageEvent;
+import android.net.metrics.IpReachabilityMonitorProbeEvent;
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkErrorMessage;
 import android.net.netlink.NetlinkMessage;
@@ -162,7 +164,7 @@
     private boolean mRunning;
 
     /**
-     * Make the kernel to perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
+     * Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
      * for the given IP address on the specified interface index.
      *
      * @return true, if the request was successfully passed to the kernel; false otherwise.
@@ -203,7 +205,8 @@
         } catch (ErrnoException | InterruptedIOException | SocketException e) {
             Log.d(TAG, "Error " + msgSnippet, e);
         }
-
+        IpReachabilityMonitorProbeEvent.logEvent("ifindex-" + ifIndex, ip.getHostAddress(),
+                returnValue);
         return returnValue;
     }
 
@@ -400,8 +403,7 @@
         return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
     }
 
-
-    // TODO: simply the number of objects by making this extend Thread.
+    // TODO: simplify the number of objects by making this extend Thread.
     private final class NetlinkSocketObserver implements Runnable {
         private NetlinkSocket mSocket;
 
@@ -519,6 +521,8 @@
 
             final short msgType = neighMsg.getHeader().nlmsg_type;
             final short nudState = ndMsg.ndm_state;
+            IpReachabilityMonitorMessageEvent.logEvent(maybeGetInterfaceName(mInterfaceIndex),
+                    destination.getHostAddress(), msgType, nudState);
             final String eventMsg = "NeighborEvent{"
                     + "elapsedMs=" + whenMs + ", "
                     + destination.getHostAddress() + ", "
@@ -549,4 +553,11 @@
             }
         }
     }
+
+    private String maybeGetInterfaceName(int index) {
+        if (index == mInterfaceIndex) {
+            return mInterfaceName;
+        }
+        return "ifindex-" + index;
+    }
 }
diff --git a/services/net/java/android/net/metrics/CaptivePortalCheckResultEvent.java b/services/net/java/android/net/metrics/CaptivePortalCheckResultEvent.java
new file mode 100644
index 0000000..163f7e40
--- /dev/null
+++ b/services/net/java/android/net/metrics/CaptivePortalCheckResultEvent.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class CaptivePortalCheckResultEvent extends IpConnectivityEvent implements Parcelable {
+    public static final String TAG = "CaptivePortalCheckResultEvent";
+
+    private int mNetId;
+    private int mResult;
+
+    public CaptivePortalCheckResultEvent(int netId, int result) {
+        mNetId = netId;
+        mResult = result;
+    }
+
+    public CaptivePortalCheckResultEvent(Parcel in) {
+        mNetId = in.readInt();
+        mResult = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mNetId);
+        out.writeInt(mResult);
+    }
+
+    public static final Parcelable.Creator<CaptivePortalCheckResultEvent> CREATOR
+        = new Parcelable.Creator<CaptivePortalCheckResultEvent>() {
+            public CaptivePortalCheckResultEvent createFromParcel(Parcel in) {
+                return new CaptivePortalCheckResultEvent(in);
+            }
+
+            public CaptivePortalCheckResultEvent[] newArray(int size) {
+                return new CaptivePortalCheckResultEvent[size];
+            }
+        };
+
+    public static void logEvent(int netId, int result) {
+        IpConnectivityEvent.logEvent(IpConnectivityEvent.IPCE_NETMON_CHECK_RESULT,
+                new CaptivePortalCheckResultEvent(netId, result));
+    }
+};
diff --git a/services/net/java/android/net/metrics/CaptivePortalStateChangeEvent.java b/services/net/java/android/net/metrics/CaptivePortalStateChangeEvent.java
new file mode 100644
index 0000000..d0cc120
--- /dev/null
+++ b/services/net/java/android/net/metrics/CaptivePortalStateChangeEvent.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class CaptivePortalStateChangeEvent extends IpConnectivityEvent implements Parcelable {
+    public static final String TAG = "CaptivePortalStateChangeEvent";
+
+    public static final int NETWORK_MONITOR_CONNECTED = 0;
+    public static final int NETWORK_MONITOR_DISCONNECTED = 1;
+    public static final int NETWORK_MONITOR_VALIDATED = 2;
+    private int mState;
+
+    public CaptivePortalStateChangeEvent(int state) {
+        mState = state;
+    }
+
+    public CaptivePortalStateChangeEvent(Parcel in) {
+        mState = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mState);
+    }
+
+    public static final Parcelable.Creator<CaptivePortalStateChangeEvent> CREATOR
+        = new Parcelable.Creator<CaptivePortalStateChangeEvent>() {
+        public CaptivePortalStateChangeEvent createFromParcel(Parcel in) {
+            return new CaptivePortalStateChangeEvent(in);
+        }
+
+        public CaptivePortalStateChangeEvent[] newArray(int size) {
+            return new CaptivePortalStateChangeEvent[size];
+        }
+    };
+
+    public static void logEvent(int state) {
+        IpConnectivityEvent.logEvent(IpConnectivityEvent.IPCE_NETMON_STATE_CHANGE,
+                new CaptivePortalStateChangeEvent(state));
+    }
+};
diff --git a/services/net/java/android/net/metrics/ConnectivityServiceChangeEvent.java b/services/net/java/android/net/metrics/ConnectivityServiceChangeEvent.java
new file mode 100644
index 0000000..92b376c
--- /dev/null
+++ b/services/net/java/android/net/metrics/ConnectivityServiceChangeEvent.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class ConnectivityServiceChangeEvent extends IpConnectivityEvent implements Parcelable {
+    public static final String TAG = "ConnectivityServiceChangeEvent";
+
+    private int mNetId;
+
+    public ConnectivityServiceChangeEvent(int netId) {
+        mNetId = netId;
+    }
+
+    public ConnectivityServiceChangeEvent(Parcel in) {
+        mNetId = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mNetId);
+    }
+
+    public static final Parcelable.Creator<ConnectivityServiceChangeEvent> CREATOR
+        = new Parcelable.Creator<ConnectivityServiceChangeEvent>() {
+        public ConnectivityServiceChangeEvent createFromParcel(Parcel in) {
+            return new ConnectivityServiceChangeEvent(in);
+        }
+
+        public ConnectivityServiceChangeEvent[] newArray(int size) {
+            return new ConnectivityServiceChangeEvent[size];
+        }
+    };
+
+    public static void logEvent(int netId) {
+        IpConnectivityEvent.logEvent(IpConnectivityEvent.IPCE_CONSRV_DEFAULT_NET_CHANGE,
+                new ConnectivityServiceChangeEvent(netId));
+    }
+};
diff --git a/services/net/java/android/net/metrics/DhcpClientEvent.java b/services/net/java/android/net/metrics/DhcpClientEvent.java
new file mode 100644
index 0000000..2c24034
--- /dev/null
+++ b/services/net/java/android/net/metrics/DhcpClientEvent.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class DhcpClientEvent extends IpConnectivityEvent implements Parcelable {
+    public static final String TAG = "DhcpClientEvent";
+
+    private String mIfName;
+    private String mMsg;
+
+    public DhcpClientEvent(String ifName, String msg) {
+        mIfName = ifName;
+        mMsg = msg;
+    }
+
+    public DhcpClientEvent(Parcel in) {
+        mIfName = in.readString();
+        mMsg = in.readString();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mIfName);
+        out.writeString(mMsg);
+    }
+
+    public static final Parcelable.Creator<DhcpClientEvent> CREATOR
+        = new Parcelable.Creator<DhcpClientEvent>() {
+        public DhcpClientEvent createFromParcel(Parcel in) {
+            return new DhcpClientEvent(in);
+        }
+
+        public DhcpClientEvent[] newArray(int size) {
+            return new DhcpClientEvent[size];
+        }
+    };
+
+    public static void logEvent(int eventType, String ifName, String msg) {
+        IpConnectivityEvent.logEvent(eventType, new DhcpClientEvent(ifName, msg));
+    }
+};
diff --git a/services/net/java/android/net/metrics/IpConnectivityEvent.java b/services/net/java/android/net/metrics/IpConnectivityEvent.java
new file mode 100644
index 0000000..f277bd0
--- /dev/null
+++ b/services/net/java/android/net/metrics/IpConnectivityEvent.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.net.ConnectivityMetricsLogger;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class IpConnectivityEvent implements Parcelable {
+    // IPRM = IpReachabilityMonitor
+    // DHCP = DhcpClient
+    // NETMON = NetworkMonitorEvent
+    // CONSRV = ConnectivityServiceEvent
+    public static final String TAG = "IpConnectivityEvent";
+    public static final int IPCE_IPRM_BASE = 0*1024;
+    public static final int IPCE_DHCP_BASE = 1*1024;
+    public static final int IPCE_NETMON_BASE = 2*1024;
+    public static final int IPCE_CONSRV_BASE = 3*1024;
+
+    public static final int IPCE_IPRM_PROBE_RESULT = IPCE_IPRM_BASE + 0;
+    public static final int IPCE_IPRM_MESSAGE_RECEIVED = IPCE_IPRM_BASE + 1;
+    public static final int IPCE_DHCP_RECV_ERROR = IPCE_DHCP_BASE + 0;
+    public static final int IPCE_DHCP_PARSE_ERROR = IPCE_DHCP_BASE + 1;
+    public static final int IPCE_DHCP_TIMEOUT = IPCE_DHCP_BASE + 2;
+    public static final int IPCE_DHCP_STATE_CHANGE = IPCE_DHCP_BASE + 3;
+    public static final int IPCE_NETMON_STATE_CHANGE = IPCE_NETMON_BASE + 0;
+    public static final int IPCE_NETMON_CHECK_RESULT = IPCE_NETMON_BASE + 1;
+    public static final int IPCE_CONSRV_DEFAULT_NET_CHANGE = IPCE_CONSRV_BASE + 0;
+
+    private static ConnectivityMetricsLogger mMetricsLogger = new ConnectivityMetricsLogger();
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+    }
+
+    public static void logEvent(int tag, IpConnectivityEvent event) {
+        long timestamp = System.currentTimeMillis();
+        mMetricsLogger.logEvent(timestamp, ConnectivityMetricsLogger.COMPONENT_TAG_CONNECTIVITY,
+                tag, event);
+    }
+};
diff --git a/services/net/java/android/net/metrics/IpReachabilityMonitorMessageEvent.java b/services/net/java/android/net/metrics/IpReachabilityMonitorMessageEvent.java
new file mode 100644
index 0000000..a8c18d6
--- /dev/null
+++ b/services/net/java/android/net/metrics/IpReachabilityMonitorMessageEvent.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class IpReachabilityMonitorMessageEvent extends IpConnectivityEvent
+    implements Parcelable {
+    public static final String TAG = "IpReachabilityMonitorMessageEvent";
+
+    private String mIfName;
+    private String mDestination;
+    private int mMsgType;
+    private int mNudState;
+
+    public IpReachabilityMonitorMessageEvent(String ifName, String destination, int msgType,
+            int nudState) {
+        mIfName = ifName;
+        mDestination = destination;
+        mMsgType = msgType;
+        mNudState = nudState;
+    }
+
+    public IpReachabilityMonitorMessageEvent(Parcel in) {
+        mIfName = in.readString();
+        mDestination = in.readString();
+        mMsgType = in.readInt();
+        mNudState = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mIfName);
+        out.writeString(mDestination);
+        out.writeInt(mMsgType);
+        out.writeInt(mNudState);
+    }
+
+    public static final Parcelable.Creator<IpReachabilityMonitorMessageEvent> CREATOR
+        = new Parcelable.Creator<IpReachabilityMonitorMessageEvent>() {
+        public IpReachabilityMonitorMessageEvent createFromParcel(Parcel in) {
+            return new IpReachabilityMonitorMessageEvent(in);
+        }
+
+        public IpReachabilityMonitorMessageEvent[] newArray(int size) {
+            return new IpReachabilityMonitorMessageEvent[size];
+        }
+    };
+
+    public static void logEvent(String ifName, String destination, int msgType, int nudState) {
+        IpConnectivityEvent.logEvent(IpConnectivityEvent.IPCE_IPRM_MESSAGE_RECEIVED,
+                new IpReachabilityMonitorMessageEvent(ifName, destination, msgType, nudState));
+    }
+};
diff --git a/services/net/java/android/net/metrics/IpReachabilityMonitorProbeEvent.java b/services/net/java/android/net/metrics/IpReachabilityMonitorProbeEvent.java
new file mode 100644
index 0000000..172cbf8
--- /dev/null
+++ b/services/net/java/android/net/metrics/IpReachabilityMonitorProbeEvent.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.metrics;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class IpReachabilityMonitorProbeEvent extends IpConnectivityEvent
+    implements Parcelable {
+    public static final String TAG = "IpReachabilityMonitorProbeEvent";
+
+    private String mIfName;
+    private String mDestination;
+    private boolean mSuccess;
+
+    public IpReachabilityMonitorProbeEvent(String ifName, String destination, boolean success) {
+        mIfName = ifName;
+        mDestination = destination;
+        mSuccess = success;
+    }
+
+    public IpReachabilityMonitorProbeEvent(Parcel in) {
+        mIfName = in.readString();
+        mDestination = in.readString();
+        mSuccess = in.readByte() > 0 ? true : false;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mIfName);
+        out.writeString(mDestination);
+        out.writeByte((byte)(mSuccess ? 1 : 0));
+    }
+
+    public static final Parcelable.Creator<IpReachabilityMonitorProbeEvent> CREATOR
+        = new Parcelable.Creator<IpReachabilityMonitorProbeEvent>() {
+        public IpReachabilityMonitorProbeEvent createFromParcel(Parcel in) {
+            return new IpReachabilityMonitorProbeEvent(in);
+        }
+
+        public IpReachabilityMonitorProbeEvent[] newArray(int size) {
+            return new IpReachabilityMonitorProbeEvent[size];
+        }
+    };
+
+    public static void logEvent(String ifName, String destination, boolean success) {
+        IpConnectivityEvent.logEvent(IpConnectivityEvent.IPCE_IPRM_PROBE_RESULT,
+                new IpReachabilityMonitorProbeEvent(ifName, destination, success));
+    }
+};
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 8cfc4a3..985917b 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -129,7 +129,7 @@
                 }
                 resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
                 resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -151,7 +151,7 @@
                     return null;
                 }
                 resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -176,7 +176,7 @@
                     return null;
                 }
                 resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -197,7 +197,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return null;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -222,7 +222,7 @@
                     return;
                 }
                 resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -247,7 +247,7 @@
                     return;
                 }
                 resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -269,7 +269,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return null;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -303,7 +303,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -325,7 +325,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -347,7 +347,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -373,7 +373,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -394,7 +394,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -415,7 +415,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -436,7 +436,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -457,7 +457,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -481,7 +481,7 @@
                     return;
                 }
                 resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -503,7 +503,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -525,7 +525,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -547,7 +547,7 @@
                 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                     return;
                 }
-                userState = getOrCreateUserStateLocked(resolvedUserId);
+                userState = getOrCreateUserStateLocked(resolvedUserId, false);
             }
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -661,7 +661,7 @@
                 @Override
                 public void onPackageModified(String packageName) {
                     if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
-                    UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+                    UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false);
 
                     synchronized (mLock) {
                         if (hadPrintService(userState, packageName)
@@ -676,7 +676,7 @@
                 @Override
                 public void onPackageRemoved(String packageName, int uid) {
                     if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
-                    UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+                    UserState userState = getOrCreateUserStateLocked(getChangingUserId(), false);
 
                     synchronized (mLock) {
                         if (hadPrintService(userState, packageName)) {
@@ -695,7 +695,8 @@
                         // A background user/profile's print jobs are running but there is
                         // no UI shown. Hence, if the packages of such a user change we need
                         // to handle it as the change may affect ongoing print jobs.
-                        UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+                        UserState userState = getOrCreateUserStateLocked(getChangingUserId(),
+                                false);
                         boolean stoppedSomePackages = false;
 
                         List<PrintServiceInfo> enabledServices = userState
@@ -730,7 +731,8 @@
                     if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
                     synchronized (mLock) {
                         if (hasPrintService(packageName)) {
-                            UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+                            UserState userState = getOrCreateUserStateLocked(getChangingUserId(),
+                                    false);
                             userState.updateIfNeededLocked();
                         }
                     }
@@ -742,7 +744,7 @@
                     UserHandle.ALL, true);
         }
 
-        private UserState getOrCreateUserStateLocked(int userId) {
+        private UserState getOrCreateUserStateLocked(int userId, boolean lowPriority) {
             if (!mUserManager.isUserUnlocked(userId)) {
                 throw new IllegalStateException(
                         "User " + userId + " must be unlocked for printing to be available");
@@ -750,9 +752,14 @@
 
             UserState userState = mUserStates.get(userId);
             if (userState == null) {
-                userState = new UserState(mContext, userId, mLock);
+                userState = new UserState(mContext, userId, mLock, lowPriority);
                 mUserStates.put(userId, userState);
             }
+
+            if (!lowPriority) {
+                userState.increasePriority();
+            }
+
             return userState;
         }
 
@@ -764,7 +771,7 @@
                 public void run() {
                     UserState userState;
                     synchronized (mLock) {
-                        userState = getOrCreateUserStateLocked(userId);
+                        userState = getOrCreateUserStateLocked(userId, true);
                         userState.updateIfNeededLocked();
                     }
                     // This is the first time we switch to this user after boot, so
diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java
index 9b99c67..9c3a852 100644
--- a/services/print/java/com/android/server/print/RemotePrintService.java
+++ b/services/print/java/com/android/server/print/RemotePrintService.java
@@ -19,6 +19,7 @@
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -813,6 +814,20 @@
         }
 
         @Override
+        public void setStatusRes(@NonNull PrintJobId printJobId, @StringRes int status,
+                @NonNull CharSequence appPackageName) {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    service.mSpooler.setStatus(printJobId, status, appPackageName);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+
+        @Override
         @SuppressWarnings({"rawtypes", "unchecked"})
         public void onPrintersAdded(ParceledListSlice printers) {
             RemotePrintService service = mWeakService.get();
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index e1d8c6c..07cc9c0 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -19,6 +19,7 @@
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -97,6 +98,8 @@
 
     private final PrintSpoolerCallbacks mCallbacks;
 
+    private boolean mIsLowPriority;
+
     private IPrintSpooler mRemoteInstance;
 
     private boolean mDestroyed;
@@ -109,17 +112,42 @@
         public void onPrintJobStateChanged(PrintJobInfo printJob);
     }
 
-    public RemotePrintSpooler(Context context, int userId,
+    public RemotePrintSpooler(Context context, int userId, boolean lowPriority,
             PrintSpoolerCallbacks callbacks) {
         mContext = context;
         mUserHandle = new UserHandle(userId);
         mCallbacks = callbacks;
+        mIsLowPriority = lowPriority;
         mClient = new PrintSpoolerClient(this);
         mIntent = new Intent();
         mIntent.setComponent(new ComponentName(PrintManager.PRINT_SPOOLER_PACKAGE_NAME,
                 PrintManager.PRINT_SPOOLER_PACKAGE_NAME + ".model.PrintSpoolerService"));
     }
 
+    public void increasePriority() {
+        if (mIsLowPriority) {
+            mIsLowPriority = false;
+
+            synchronized (mLock) {
+                throwIfDestroyedLocked();
+
+                while (!mCanUnbind) {
+                    try {
+                        mLock.wait();
+                    } catch (InterruptedException e) {
+                        Slog.e(LOG_TAG, "Interrupted while waiting for operation to complete");
+                    }
+                }
+
+                if (DEBUG) {
+                    Slog.i(LOG_TAG, "Unbinding as previous binding was low priority");
+                }
+
+                unbindLocked();
+            }
+        }
+    }
+
     public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state,
             int appId) {
         throwIfCalledOnMainThread();
@@ -301,6 +329,35 @@
     }
 
     /**
+     * Set status of a print job.
+     *
+     * @param printJobId The print job to update
+     * @param status The new status as a string resource
+     * @param appPackageName The app package name the string res belongs to
+     */
+    public final void setStatus(@NonNull PrintJobId printJobId, @StringRes int status,
+            @NonNull CharSequence appPackageName) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            getRemoteInstanceLazy().setStatusRes(printJobId, status, appPackageName);
+        } catch (RemoteException|TimeoutException re) {
+            Slog.e(LOG_TAG, "Error setting status.", re);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+    }
+
+    /**
      * Handle that a custom icon for a printer was loaded.
      *
      * @param printerId the id of the printer the icon belongs to
@@ -549,11 +606,18 @@
             return;
         }
         if (DEBUG) {
-            Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked()");
+            Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked() " +
+                    (mIsLowPriority ? "low priority" : ""));
         }
 
-        mContext.bindServiceAsUser(mIntent, mServiceConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, mUserHandle);
+        int flags;
+        if (mIsLowPriority) {
+            flags = Context.BIND_AUTO_CREATE;
+        } else {
+            flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+        }
+
+        mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle);
 
         final long startMillis = SystemClock.uptimeMillis();
         while (true) {
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 8ab1878..263dead 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -126,11 +126,11 @@
 
     private boolean mDestroyed;
 
-    public UserState(Context context, int userId, Object lock) {
+    public UserState(Context context, int userId, Object lock, boolean lowPriority) {
         mContext = context;
         mUserId = userId;
         mLock = lock;
-        mSpooler = new RemotePrintSpooler(context, userId, this);
+        mSpooler = new RemotePrintSpooler(context, userId, lowPriority, this);
         mHandler = new UserStateHandler(context.getMainLooper());
 
         synchronized (mLock) {
@@ -145,6 +145,10 @@
         }
     }
 
+    public void increasePriority() {
+        mSpooler.increasePriority();
+    }
+
     @Override
     public void onPrintJobQueued(PrintJobInfo printJob) {
         final RemotePrintService service;
diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
index c322ab8..876d95b 100644
--- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
+++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
@@ -631,18 +631,10 @@
         byte[] hwaddr = {
                 (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a
         };
-        byte[] params = new byte[] {
-            DHCP_SUBNET_MASK,
-            DHCP_ROUTER,
-            DHCP_DNS_SERVER,
-            DHCP_DOMAIN_NAME,
-            DHCP_MTU,
-            DHCP_LEASE_TIME,
-        };
 
         ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
                 DhcpPacket.ENCAP_L2, transactionId, secs, hwaddr,
-                false /* do unicast */, params);
+                false /* do unicast */, DhcpClient.REQUESTED_PARAMS);
 
         byte[] headers = new byte[] {
             // Ethernet header.
@@ -650,14 +642,14 @@
             (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
             (byte) 0x08, (byte) 0x00,
             // IP header.
-            (byte) 0x45, (byte) 0x10, (byte) 0x01, (byte) 0x52,
+            (byte) 0x45, (byte) 0x10, (byte) 0x01, (byte) 0x56,
             (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00,
-            (byte) 0x40, (byte) 0x11, (byte) 0x39, (byte) 0x8c,
+            (byte) 0x40, (byte) 0x11, (byte) 0x39, (byte) 0x88,
             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
             // UDP header.
             (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x43,
-            (byte) 0x01, (byte) 0x3e, (byte) 0xd8, (byte) 0xa4,
+            (byte) 0x01, (byte) 0x42, (byte) 0x6a, (byte) 0x4a,
             // BOOTP.
             (byte) 0x01, (byte) 0x01, (byte) 0x06, (byte) 0x00,
             (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
@@ -688,13 +680,17 @@
                     'a', 'n', 'd', 'r', 'o', 'i', 'd', '-',
                     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e',
             // Requested parameter list.
-            (byte) 0x37, (byte) 0x06,
+            (byte) 0x37, (byte) 0x0a,
                 DHCP_SUBNET_MASK,
                 DHCP_ROUTER,
                 DHCP_DNS_SERVER,
                 DHCP_DOMAIN_NAME,
                 DHCP_MTU,
+                DHCP_BROADCAST_ADDRESS,
                 DHCP_LEASE_TIME,
+                DHCP_RENEWAL_TIME,
+                DHCP_REBINDING_TIME,
+                DHCP_VENDOR_INFO,
             // End options.
             (byte) 0xff,
             // Our packets are always of even length. TODO: find out why and possibly fix it.
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 72a458b..622e46e 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -313,7 +313,7 @@
     public void testScreenChangesRules() throws Exception {
         Future<Void> future;
 
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, true);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -322,7 +322,7 @@
         verifyAndReset();
 
         // push strict policy for foreground uid, verify ALLOW rule
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, true);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -332,7 +332,7 @@
 
         // now turn screen off and verify REJECT rule
         expect(mPowerManager.isInteractive()).andReturn(false).atLeastOnce();
-        expectSetUidNetworkRules(UID_A, true);
+        expectSetUidMeteredNetworkBlacklist(UID_A, true);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
         replay();
@@ -342,7 +342,7 @@
 
         // and turn screen back on, verify ALLOW rule restored
         expect(mPowerManager.isInteractive()).andReturn(true).atLeastOnce();
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, true);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -354,7 +354,7 @@
     public void testPolicyNone() throws Exception {
         Future<Void> future;
 
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, true);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -363,7 +363,7 @@
         verifyAndReset();
 
         // POLICY_NONE should RULE_ALLOW in foreground
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, true);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -372,7 +372,7 @@
         verifyAndReset();
 
         // POLICY_NONE should RULE_ALLOW in background
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -385,7 +385,7 @@
         Future<Void> future;
 
         // POLICY_REJECT should RULE_ALLOW in background
-        expectSetUidNetworkRules(UID_A, true);
+        expectSetUidMeteredNetworkBlacklist(UID_A, true);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
         replay();
@@ -394,7 +394,7 @@
         verifyAndReset();
 
         // POLICY_REJECT should RULE_ALLOW in foreground
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, true);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -403,7 +403,7 @@
         verifyAndReset();
 
         // POLICY_REJECT should RULE_REJECT in background
-        expectSetUidNetworkRules(UID_A, true);
+        expectSetUidMeteredNetworkBlacklist(UID_A, true);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
         replay();
@@ -416,7 +416,7 @@
         Future<Void> future;
 
         // POLICY_NONE should have RULE_ALLOW in background
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -426,7 +426,7 @@
         verifyAndReset();
 
         // adding POLICY_REJECT should cause RULE_REJECT
-        expectSetUidNetworkRules(UID_A, true);
+        expectSetUidMeteredNetworkBlacklist(UID_A, true);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
         replay();
@@ -435,7 +435,7 @@
         verifyAndReset();
 
         // removing POLICY_REJECT should return us to RULE_ALLOW
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -632,7 +632,7 @@
         Future<Void> future;
 
         // POLICY_REJECT should RULE_REJECT in background
-        expectSetUidNetworkRules(UID_A, true);
+        expectSetUidMeteredNetworkBlacklist(UID_A, true);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
         replay();
@@ -641,7 +641,7 @@
         verifyAndReset();
 
         // uninstall should clear RULE_REJECT
-        expectSetUidNetworkRules(UID_A, false);
+        expectSetUidMeteredNetworkBlacklist(UID_A, false);
         expectSetUidForeground(UID_A, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
         replay();
@@ -890,9 +890,9 @@
         expectLastCall().atLeastOnce();
     }
 
-    private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces)
+    private void expectSetUidMeteredNetworkBlacklist(int uid, boolean rejectOnQuotaInterfaces)
             throws Exception {
-        mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
+        mNetworkManager.setUidMeteredNetworkBlacklist(uid, rejectOnQuotaInterfaces);
         expectLastCall().atLeastOnce();
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
index 28966ca..a30d2b5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
@@ -32,19 +32,23 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.ILauncherApps;
 import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.content.pm.ShortcutServiceInternal;
+import android.content.pm.Signature;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.BitmapFactory;
 import android.graphics.drawable.Icon;
+import android.net.Uri;
 import android.os.BaseBundle;
 import android.os.Bundle;
 import android.os.FileUtils;
@@ -103,7 +107,6 @@
  * TODO: separate, detailed tests for ShortcutInfo (CTS?) *
  *
  * TODO: Cross-user test (do in CTS?)
- *
  */
 @SmallTest
 public class ShortcutManagerTest extends InstrumentationTestCase {
@@ -217,8 +220,7 @@
 
         @Override
         int injectGetPackageUid(String packageName, int userId) {
-            Integer uid = mInjectedPackageUidMap.get(packageName);
-            return UserHandle.getUid(getCallingUserId(), (uid != null ? uid : 0));
+            return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid;
         }
 
         @Override
@@ -253,6 +255,12 @@
         }
 
         @Override
+        PackageInfo injectPackageInfo(String packageName, @UserIdInt int userId,
+                boolean getSignatures) {
+            return getInjectedPackageInfo(packageName, userId, getSignatures);
+        }
+
+        @Override
         void postToHandler(Runnable r) {
             final long token = mContext.injectClearCallingIdentity();
             super.postToHandler(r);
@@ -355,7 +363,7 @@
     private int mInjectedCallingUid;
     private String mInjectedClientPackage;
 
-    private Map<String, Integer> mInjectedPackageUidMap;
+    private Map<String, PackageInfo> mInjectedPackages;
 
     private PackageManager mMockPackageManager;
     private PackageManagerInternal mMockPackageManagerInternal;
@@ -407,12 +415,12 @@
 
         mInjectedCurrentTimeLillis = START_TIME;
 
-        mInjectedPackageUidMap = new HashMap<>();
-        mInjectedPackageUidMap.put(CALLING_PACKAGE_1, CALLING_UID_1);
-        mInjectedPackageUidMap.put(CALLING_PACKAGE_2, CALLING_UID_2);
-        mInjectedPackageUidMap.put(CALLING_PACKAGE_3, CALLING_UID_3);
-        mInjectedPackageUidMap.put(LAUNCHER_1, LAUNCHER_UID_1);
-        mInjectedPackageUidMap.put(LAUNCHER_2, LAUNCHER_UID_2);
+        mInjectedPackages = new HashMap<>();;
+        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1);
+        addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 2);
+        addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 3);
+        addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4);
+        addPackage(LAUNCHER_2, LAUNCHER_UID_2, 5);
 
         mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");
 
@@ -448,12 +456,57 @@
         mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
     }
 
+    private void addPackage(String packageName, int uid, int version) {
+        addPackage(packageName, uid, version, packageName);
+    }
+
+    private Signature[] genSignatures(String... signatures) {
+        final Signature[] sigs = new Signature[signatures.length];
+        for (int i = 0; i < signatures.length; i++){
+            sigs[i] = new Signature(signatures[i].getBytes());
+        }
+        return sigs;
+    }
+
+    private PackageInfo genPackage(String packageName, int uid, int version, String... signatures) {
+        final PackageInfo pi = new PackageInfo();
+        pi.packageName = packageName;
+        pi.applicationInfo = new ApplicationInfo();
+        pi.applicationInfo.uid = uid;
+        pi.versionCode = version;
+        pi.signatures = genSignatures(signatures);
+
+        return pi;
+    }
+
+    private void addPackage(String packageName, int uid, int version, String... signatures) {
+        mInjectedPackages.put(packageName, genPackage(packageName, uid, version, signatures));
+    }
+
+    PackageInfo getInjectedPackageInfo(String packageName, @UserIdInt int userId,
+            boolean getSignatures) {
+        final PackageInfo pi = mInjectedPackages.get(packageName);
+        if (pi == null) return null;
+
+        final PackageInfo ret = new PackageInfo();
+        ret.packageName = pi.packageName;
+        ret.versionCode = pi.versionCode;
+        ret.applicationInfo = new ApplicationInfo(pi.applicationInfo);
+        ret.applicationInfo.uid = UserHandle.getUid(userId, pi.applicationInfo.uid);
+
+        if (getSignatures) {
+            ret.signatures = pi.signatures;
+        }
+
+        return ret;
+    }
+
     /** Replace the current calling package */
     private void setCaller(String packageName, int userId) {
         mInjectedClientPackage = packageName;
-        mInjectedCallingUid = UserHandle.getUid(userId,
-                Preconditions.checkNotNull(mInjectedPackageUidMap.get(packageName),
-                        "Unknown package"));
+        mInjectedCallingUid =
+                Preconditions.checkNotNull(getInjectedPackageInfo(packageName, userId, false),
+                        "Unknown package").applicationInfo.uid;
     }
 
     private void setCaller(String packageName) {
@@ -466,13 +519,13 @@
 
     private void runWithCaller(String packageName, int userId, Runnable r) {
         final String previousPackage = mInjectedClientPackage;
-        final int previousUid = mInjectedCallingUid;
+        final int previousUserId = UserHandle.getUserId(mInjectedCallingUid);
 
         setCaller(packageName, userId);
 
         r.run();
 
-        setCaller(previousPackage, previousUid);
+        setCaller(previousPackage, previousUserId);
     }
 
     private int getCallingUserId() {
@@ -852,6 +905,18 @@
         assertTrue(b == null || b.size() == 0);
     }
 
+    private void assertShortcutPackageInfo(String packageName, int userId, int expectedVersion) {
+        ShortcutPackageInfo spi = mService.getPackageInfoForTest(packageName, userId);
+        assertNotNull(spi);
+        assertEquals(expectedVersion, spi.getVersionCode());
+
+        assertTrue(spi.canRestoreTo(genPackage(packageName, /*uid*/ 0, 9999999, packageName)));
+    }
+
+    private void assertNoShortcutPackageInfo(String packageName, int userId) {
+        assertNull(mService.getPackageInfoForTest(packageName, userId));
+    }
+
     private ShortcutInfo getPackageShortcut(String packageName, String shortcutId, int userId) {
         return mService.getPackageShortcutForTest(packageName, shortcutId, userId);
     }
@@ -886,6 +951,22 @@
         return getLauncherShortcuts(launcher, userId, ShortcutQuery.FLAG_GET_PINNED);
     }
 
+
+    private Intent genPackageDeleteIntent(String pakcageName, int userId) {
+        Intent i = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+        i.setData(Uri.parse("package:" + pakcageName));
+        i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+        return i;
+    }
+
+    private Intent genPackageUpdateIntent(String pakcageName, int userId) {
+        Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
+        i.setData(Uri.parse("package:" + pakcageName));
+        i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+        i.putExtra(Intent.EXTRA_REPLACING, true);
+        return i;
+    }
+
     /**
      * Wrap a set in an ArraySet just to get a better toString.
      */
@@ -1017,6 +1098,8 @@
     }
 
     public void testSetDynamicShortcuts() {
+        setCaller(CALLING_PACKAGE_1, USER_0);
+
         final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
         final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.icon2));
@@ -1045,6 +1128,11 @@
                 "shortcut1", "shortcut2");
         assertEquals(2, mManager.getRemainingCallCount());
 
+        assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+        assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_0);
+        assertNoShortcutPackageInfo(CALLING_PACKAGE_1, USER_10);
+        assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_10);
+
         // TODO: Check fields
 
         assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1)));
@@ -1068,9 +1156,20 @@
         assertEquals(2, mManager.getDynamicShortcuts().size());
 
         // TODO Check max number
+
+        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+            assertTrue(mManager.setDynamicShortcuts(Arrays.asList(makeShortcut("s1"))));
+
+            assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+            assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_0);
+            assertNoShortcutPackageInfo(CALLING_PACKAGE_1, USER_10);
+            assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_10, 2);
+        });
     }
 
     public void testAddDynamicShortcuts() {
+        setCaller(CALLING_PACKAGE_1, USER_0);
+
         final ShortcutInfo si1 = makeShortcut("shortcut1");
         final ShortcutInfo si2 = makeShortcut("shortcut2");
         final ShortcutInfo si3 = makeShortcut("shortcut3");
@@ -1099,6 +1198,11 @@
         // TODO Check max number
 
         // TODO Check fields.
+
+        runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+            assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+            assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_10, 2);
+        });
     }
 
     public void testDeleteDynamicShortcut() {
@@ -1691,6 +1795,15 @@
         // TODO Check with other fields too.
 
         // TODO Check bitmap removal too.
+
+        runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
+            assertNoShortcutPackageInfo(CALLING_PACKAGE_2, USER_11);
+
+            mManager.updateShortcuts(Arrays.asList());
+
+            // Even an empty update call will populate the package info.
+            assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_11, 2);
+        });
     }
 
     // TODO: updateShortcuts()
@@ -1886,9 +1999,16 @@
 
         // Pin some.
         runWithCaller(LAUNCHER_1, USER_0, () -> {
+            assertNoShortcutPackageInfo(LAUNCHER_1, USER_0);
+
             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
                     Arrays.asList("s2", "s3"), getCallingUser());
 
+            assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+            assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
+            assertNoShortcutPackageInfo(LAUNCHER_1, USER_10);
+            assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
+
             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
                     Arrays.asList("s3", "s4", "s5"), getCallingUser());
 
@@ -1949,11 +2069,19 @@
 
         dumpsysOnLogcat();
 
+        assertNoShortcutPackageInfo(LAUNCHER_1, USER_0);
+        assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
+        assertNoShortcutPackageInfo(LAUNCHER_1, USER_10);
+        assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
+
         // Pin some.
         runWithCaller(LAUNCHER_1, USER_0, () -> {
             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
                     Arrays.asList("s3", "s4"), getCallingUser());
 
+            assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+            assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
+
             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
                     Arrays.asList("s1", "s2", "s4"), getCallingUser());
         });
@@ -2027,10 +2155,16 @@
                                     | ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
                     "s2");
 
+            assertNoShortcutPackageInfo(LAUNCHER_2, USER_0);
+            assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
+
             // Now pin some.
             mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
                     Arrays.asList("s1", "s2"), getCallingUser());
 
+            assertShortcutPackageInfo(LAUNCHER_2, USER_0, 5);
+            assertNoShortcutPackageInfo(LAUNCHER_2, USER_10);
+
             mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
                     Arrays.asList("s1", "s2"), getCallingUser());
 
@@ -2048,10 +2182,26 @@
                     "s2");
         });
 
+        assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+        assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+        assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+        assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+        assertShortcutPackageInfo(LAUNCHER_2, USER_0, 5);
+
         // Re-initialize and load from the files.
         mService.saveDirtyInfo();
         initService();
 
+        // Load from file.
+        mService.handleUnlockUser(USER_0);
+
+        // Make sure package info is restored too.
+        assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+        assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+        assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+        assertShortcutPackageInfo(LAUNCHER_1, USER_0, 4);
+        assertShortcutPackageInfo(LAUNCHER_2, USER_0, 5);
+
         runWithCaller(LAUNCHER_1, USER_0, () -> {
             assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
@@ -2489,6 +2639,10 @@
         mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM).setLauncherComponent(
                 mService, new ComponentName("pkg1", "class"));
 
+        assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+        assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+        assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+
         // Restore.
         mService.saveDirtyInfo();
         initService();
@@ -2499,6 +2653,10 @@
         // this will pre-load the per-user info.
         mService.handleUnlockUser(UserHandle.USER_SYSTEM);
 
+        assertShortcutPackageInfo(CALLING_PACKAGE_1, USER_0, 1);
+        assertShortcutPackageInfo(CALLING_PACKAGE_2, USER_0, 2);
+        assertNoShortcutPackageInfo(CALLING_PACKAGE_3, USER_0);
+
         // Now it's loaded.
         assertEquals(1, mService.getShortcutsForTest().size());
 
@@ -2637,6 +2795,11 @@
         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
         assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
 
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
         mService.saveDirtyInfo();
 
         // Nonexistent package.
@@ -2664,6 +2827,11 @@
         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
         assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
 
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
         mService.saveDirtyInfo();
 
         // Remove a package.
@@ -2690,6 +2858,11 @@
         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
         assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
 
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
         mService.saveDirtyInfo();
 
         // Remove a launcher.
@@ -2738,6 +2911,11 @@
         assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
         assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
 
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+
         mService.saveDirtyInfo();
 
         // Remove the other launcher from user 10 too.
@@ -2792,4 +2970,162 @@
     // TODO Detailed test for hasShortcutPermissionInner().
 
     // TODO Add tests for the command line functions too.
+
+    private void checkCanRestoreTo(boolean expected, ShortcutPackageInfo spi,
+            int version, String... signatures) {
+        assertEquals(expected, spi.canRestoreTo(genPackage(
+                "dummy", /* uid */ 0, version, signatures)));
+    }
+
+    public void testCanRestoreTo() {
+        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
+        addPackage(CALLING_PACKAGE_2, CALLING_UID_1, 10, "sig1", "sig2");
+
+        final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackage(
+                mService, CALLING_PACKAGE_1, USER_0);
+        final ShortcutPackageInfo spi2 = ShortcutPackageInfo.generateForInstalledPackage(
+                mService, CALLING_PACKAGE_2, USER_0);
+
+        checkCanRestoreTo(true, spi1, 10, "sig1");
+        checkCanRestoreTo(true, spi1, 10, "x", "sig1");
+        checkCanRestoreTo(true, spi1, 10, "sig1", "y");
+        checkCanRestoreTo(true, spi1, 10, "x", "sig1", "y");
+        checkCanRestoreTo(true, spi1, 11, "sig1");
+
+        checkCanRestoreTo(false, spi1, 10 /* empty */);
+        checkCanRestoreTo(false, spi1, 10, "x");
+        checkCanRestoreTo(false, spi1, 10, "x", "y");
+        checkCanRestoreTo(false, spi1, 10, "x");
+        checkCanRestoreTo(false, spi1, 9, "sig1");
+
+        checkCanRestoreTo(true, spi2, 10, "sig1", "sig2");
+        checkCanRestoreTo(true, spi2, 10, "sig2", "sig1");
+        checkCanRestoreTo(true, spi2, 10, "x", "sig1", "sig2");
+        checkCanRestoreTo(true, spi2, 10, "x", "sig2", "sig1");
+        checkCanRestoreTo(true, spi2, 10, "sig1", "sig2", "y");
+        checkCanRestoreTo(true, spi2, 10, "sig2", "sig1", "y");
+        checkCanRestoreTo(true, spi2, 10, "x", "sig1", "sig2", "y");
+        checkCanRestoreTo(true, spi2, 10, "x", "sig2", "sig1", "y");
+        checkCanRestoreTo(true, spi2, 11, "x", "sig2", "sig1", "y");
+
+        checkCanRestoreTo(false, spi2, 10, "sig1", "sig2x");
+        checkCanRestoreTo(false, spi2, 10, "sig2", "sig1x");
+        checkCanRestoreTo(false, spi2, 10, "x", "sig1x", "sig2");
+        checkCanRestoreTo(false, spi2, 10, "x", "sig2x", "sig1");
+        checkCanRestoreTo(false, spi2, 10, "sig1", "sig2x", "y");
+        checkCanRestoreTo(false, spi2, 10, "sig2", "sig1x", "y");
+        checkCanRestoreTo(false, spi2, 10, "x", "sig1x", "sig2", "y");
+        checkCanRestoreTo(false, spi2, 10, "x", "sig2x", "sig1", "y");
+        checkCanRestoreTo(false, spi2, 11, "x", "sig2x", "sig1", "y");
+    }
+
+    public void testShortcutPackageInfoRefresh() {
+        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
+
+        final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackage(
+                mService, CALLING_PACKAGE_1, USER_0);
+
+        checkCanRestoreTo(true, spi1, 10, "sig1");
+
+        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 11, "sig1", "sig2");
+
+        spi1.refreshAndSave(mService, USER_0);
+
+        mService.handleCleanupUser(USER_0);
+        initService();
+
+        checkCanRestoreTo(false, spi1, 10, "sig1", "sig2");
+        checkCanRestoreTo(false, spi1, 11, "sig", "sig2");
+        checkCanRestoreTo(false, spi1, 11, "sig1", "sig");
+        checkCanRestoreTo(true, spi1, 11, "sig1", "sig2");
+    }
+
+    public void testHandlePackageDelete() {
+        setCaller(CALLING_PACKAGE_1, USER_0);
+        assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+        setCaller(CALLING_PACKAGE_2, USER_0);
+        assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+        setCaller(CALLING_PACKAGE_3, USER_0);
+        assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+        setCaller(CALLING_PACKAGE_1, USER_10);
+        assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+        setCaller(CALLING_PACKAGE_2, USER_10);
+        assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+        setCaller(CALLING_PACKAGE_3, USER_10);
+        assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageDeleteIntent(CALLING_PACKAGE_1, USER_0));
+
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageDeleteIntent(CALLING_PACKAGE_2, USER_10));
+
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+        mInjectedPackages.remove(CALLING_PACKAGE_1);
+        mInjectedPackages.remove(CALLING_PACKAGE_3);
+
+        mService.handleUnlockUser(USER_0);
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+
+        mService.handleUnlockUser(USER_10);
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_0));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_0));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_10));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_2, USER_10));
+        assertNull(mService.getPackageInfoForTest(CALLING_PACKAGE_3, USER_10));
+    }
+
+    public void testHandlePackageUpdate() {
+        setCaller(CALLING_PACKAGE_1, USER_0);
+        assertTrue(mManager.addDynamicShortcut(makeShortcut("s1")));
+
+        assertNotNull(mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0));
+        assertEquals(1, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0).getVersionCode());
+
+        addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 123);
+
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageUpdateIntent("abc", USER_0));
+        assertEquals(1, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0).getVersionCode());
+
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageUpdateIntent("abc", USER_10));
+        assertEquals(1, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0).getVersionCode());
+
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
+        assertEquals(123, mService.getPackageInfoForTest(CALLING_PACKAGE_1, USER_0)
+                .getVersionCode());
+    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 5fe944c..08cbcf7 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -780,7 +780,7 @@
                     || ("0".equals(SystemProperties.get("persist.charging.notify")))) return;
             int id = 0;
             Resources r = mContext.getResources();
-            if (mConnected || mHostConnected) {
+            if (mConnected) {
                 if (!mUsbDataUnlocked) {
                     id = com.android.internal.R.string.usb_charging_notification_title;
                 } else if (UsbManager.containsFunction(mCurrentFunctions,
@@ -798,6 +798,8 @@
                 } else {
                     id = com.android.internal.R.string.usb_charging_notification_title;
                 }
+            } else if (mHostConnected) {
+                id = com.android.internal.R.string.usb_supplying_notification_title;
             }
             if (id != mUsbNotificationId) {
                 // clear notification if title needs changing
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index afb7d93..b4c6e6a 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -250,7 +250,7 @@
          * in its manifest.
          * <p>
          * See {@link Connection#CAPABILITY_CAN_PULL_CALL} and
-         * {@link Connection#CAPABILITY_IS_EXTERNAL_CALL}.
+         * {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
          */
         public static final int CAPABILITY_CAN_PULL_CALL = 0x00800000;
 
@@ -296,13 +296,13 @@
          * Consider, for example, a scenario where a user has two phones with the same phone number.
          * When a user places a call on one device, the telephony stack can represent that call on
          * the other device by adding it to the {@link ConnectionService} with the
-         * {@link Connection#CAPABILITY_IS_EXTERNAL_CALL} capability set.
+         * {@link Connection#PROPERTY_IS_EXTERNAL_CALL} property set.
          * <p>
          * An {@link InCallService} will only see calls with this property if it has the
          * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true}
          * in its manifest.
          * <p>
-         * See {@link Connection#CAPABILITY_IS_EXTERNAL_CALL}.
+         * See {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
          */
         public static final int PROPERTY_IS_EXTERNAL_CALL = 0x00000040;
 
@@ -686,7 +686,7 @@
             sb.append(", caps: ");
             sb.append(capabilitiesToString(mCallCapabilities));
             sb.append(", props: ");
-            sb.append(mCallProperties);
+            sb.append(propertiesToString(mCallProperties));
             sb.append("]");
             return sb.toString();
         }
@@ -813,6 +813,7 @@
     private String mRemainingPostDialSequence;
     private VideoCallImpl mVideoCallImpl;
     private Details mDetails;
+    private Bundle mExtras;
 
     /**
      * Obtains the post-dial sequence remaining to be emitted by this {@code Call}, if any.
@@ -988,6 +989,89 @@
     }
 
     /**
+     * Adds some extras to this {@link Call}.  Existing keys are replaced and new ones are
+     * added.
+     * <p>
+     * No assumptions should be made as to how an In-Call UI or service will handle these
+     * extras.  Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
+     *
+     * @param extras The extras to add.
+     */
+    public final void putExtras(Bundle extras) {
+        if (extras == null) {
+            return;
+        }
+
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putAll(extras);
+        mInCallAdapter.putExtras(mTelecomCallId, extras);
+    }
+
+    /**
+     * Adds a boolean extra to this {@link Call}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, boolean value) {
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putBoolean(key, value);
+        mInCallAdapter.putExtra(mTelecomCallId, key, value);
+    }
+
+    /**
+     * Adds an integer extra to this {@code Connection}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, int value) {
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putInt(key, value);
+        mInCallAdapter.putExtra(mTelecomCallId, key, value);
+    }
+
+    /**
+     * Adds a string extra to this {@code Connection}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, String value) {
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putString(key, value);
+        mInCallAdapter.putExtra(mTelecomCallId, key, value);
+    }
+
+    /**
+     * Removes extras from this {@code Connection}.
+     *
+     * @param keys The keys of the extras to remove.
+     */
+    public final void removeExtras(List<String> keys) {
+        if (mExtras != null) {
+            for (String key : keys) {
+                mExtras.remove(key);
+            }
+            if (mExtras.size() == 0) {
+                mExtras = null;
+            }
+        }
+        mInCallAdapter.removeExtras(mTelecomCallId, keys);
+    }
+
+    /**
      * Obtains the parent of this {@code Call} in a conference, if any.
      *
      * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 1b70d65..06851eeb 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -16,10 +16,12 @@
 
 package android.telecom;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Bundle;
 import android.telecom.Connection.VideoProvider;
+import android.util.ArraySet;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -51,10 +53,13 @@
         public void onDestroyed(Conference conference) {}
         public void onConnectionCapabilitiesChanged(
                 Conference conference, int connectionCapabilities) {}
+        public void onConnectionPropertiesChanged(
+                Conference conference, int connectionProperties) {}
         public void onVideoStateChanged(Conference c, int videoState) { }
         public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {}
         public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {}
-        public void onExtrasChanged(Conference conference, Bundle extras) {}
+        public void onExtrasChanged(Conference c, Bundle extras) {}
+        public void onExtrasRemoved(Conference c, List<String> keys) {}
     }
 
     private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
@@ -71,10 +76,12 @@
     private int mState = Connection.STATE_NEW;
     private DisconnectCause mDisconnectCause;
     private int mConnectionCapabilities;
+    private int mConnectionProperties;
     private String mDisconnectMessage;
     private long mConnectTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
     private StatusHints mStatusHints;
     private Bundle mExtras;
+    private Set<String> mPreviousExtraKeys;
 
     private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
         @Override
@@ -152,6 +159,16 @@
     }
 
     /**
+     * Returns the properties of the conference. See {@code PROPERTY_*} constants in class
+     * {@link Connection} for valid values.
+     *
+     * @return A bitmask of the properties of the conference call.
+     */
+    public final int getConnectionProperties() {
+        return mConnectionProperties;
+    }
+
+    /**
      * Whether the given capabilities support the specified capability.
      *
      * @param capabilities A capability bit field.
@@ -360,7 +377,7 @@
      * Sets the capabilities of a conference. See {@code CAPABILITY_*} constants of class
      * {@link Connection} for valid values.
      *
-     * @param connectionCapabilities A bitmask of the {@code PhoneCapabilities} of the conference call.
+     * @param connectionCapabilities A bitmask of the {@code Capabilities} of the conference call.
      */
     public final void setConnectionCapabilities(int connectionCapabilities) {
         if (connectionCapabilities != mConnectionCapabilities) {
@@ -373,6 +390,22 @@
     }
 
     /**
+     * Sets the properties of a conference. See {@code PROPERTY_*} constants of class
+     * {@link Connection} for valid values.
+     *
+     * @param connectionProperties A bitmask of the {@code Properties} of the conference call.
+     */
+    public final void setConnectionProperties(int connectionProperties) {
+        if (connectionProperties != mConnectionProperties) {
+            mConnectionProperties = connectionProperties;
+
+            for (Listener l : mListeners) {
+                l.onConnectionPropertiesChanged(this, mConnectionProperties);
+            }
+        }
+    }
+
+    /**
      * Adds the specified connection as a child of this conference.
      *
      * @param connection The connection to add.
@@ -640,23 +673,171 @@
     }
 
     /**
-     * Set some extras that can be associated with this {@code Conference}. No assumptions should
-     * be made as to how an In-Call UI or service will handle these extras.
+     * Replaces all the extras associated with this {@code Conference}.
+     * <p>
+     * New or existing keys are replaced in the {@code Conference} extras.  Keys which are no longer
+     * in the new extras, but were present the last time {@code setExtras} was called are removed.
+     * <p>
+     * No assumptions should be made as to how an In-Call UI or service will handle these extras.
      * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
      *
-     * @param extras The extras associated with this {@code Connection}.
+     * @param extras The extras associated with this {@code Conference}.
+     * @deprecated Use {@link #putExtras(Bundle)} to add extras.  Use {@link #removeExtras(List)}
+     * to remove extras.
      */
     public final void setExtras(@Nullable Bundle extras) {
-        mExtras = extras;
+        // Add/replace any new or changed extras values.
+        putExtras(extras);
+
+        // If we have used "setExtras" in the past, compare the key set from the last invocation to
+        // the current one and remove any keys that went away.
+        if (mPreviousExtraKeys != null) {
+            List<String> toRemove = new ArrayList<String>();
+            for (String oldKey : mPreviousExtraKeys) {
+                if (!extras.containsKey(oldKey)) {
+                    toRemove.add(oldKey);
+                }
+            }
+
+            if (!toRemove.isEmpty()) {
+                removeExtras(toRemove);
+            }
+        }
+
+        // Track the keys the last time set called setExtras.  This way, the next time setExtras is
+        // called we can see if the caller has removed any extras values.
+        if (mPreviousExtraKeys == null) {
+            mPreviousExtraKeys = new ArraySet<String>();
+        }
+        mPreviousExtraKeys.clear();
+        mPreviousExtraKeys.addAll(extras.keySet());
+    }
+
+    /**
+     * Adds some extras to this {@link Conference}.  Existing keys are replaced and new ones are
+     * added.
+     * <p>
+     * No assumptions should be made as to how an In-Call UI or service will handle these extras.
+     * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
+     *
+     * @param extras The extras to add.
+     */
+    public final void putExtras(@NonNull Bundle extras) {
+        if (extras == null) {
+            return;
+        }
+
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putAll(extras);
+
         for (Listener l : mListeners) {
             l.onExtrasChanged(this, extras);
         }
     }
 
     /**
-     * @return The extras associated with this conference.
+     * Adds a boolean extra to this {@link Conference}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, boolean value) {
+        Bundle newExtras = new Bundle();
+        newExtras.putBoolean(key, value);
+        putExtras(newExtras);
+    }
+
+    /**
+     * Adds an integer extra to this {@link Conference}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, int value) {
+        Bundle newExtras = new Bundle();
+        newExtras.putInt(key, value);
+        putExtras(newExtras);
+    }
+
+    /**
+     * Adds a string extra to this {@link Conference}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, String value) {
+        Bundle newExtras = new Bundle();
+        newExtras.putString(key, value);
+        putExtras(newExtras);
+    }
+
+    /**
+     * Removes an extra from this {@link Conference}.
+     *
+     * @param keys The key of the extra key to remove.
+     */
+    public final void removeExtras(List<String> keys) {
+        if (keys == null || keys.isEmpty()) {
+            return;
+        }
+
+        if (mExtras != null) {
+            for (String key : keys) {
+                mExtras.remove(key);
+            }
+            if (mExtras.size() == 0) {
+                mExtras = null;
+            }
+        }
+
+        for (Listener l : mListeners) {
+            l.onExtrasRemoved(this, keys);
+        }
+    }
+
+    /**
+     * Returns the extras associated with this conference.
+     * <p>
+     * Extras should be updated using {@link #putExtras(Bundle)} and {@link #removeExtras(List)}.
+     * <p>
+     * Telecom or an {@link InCallService} can also update the extras via
+     * {@link android.telecom.Call#putExtras(Bundle)}, and
+     * {@link Call#removeExtras(List)}.
+     * <p>
+     * The conference is notified of changes to the extras made by Telecom or an
+     * {@link InCallService} by {@link #onExtrasChanged(Bundle)}.
+     *
+     * @return The extras associated with this connection.
      */
     public final Bundle getExtras() {
         return mExtras;
     }
+
+    /**
+     * Notifies this {@link Conference} of a change to the extras made outside the
+     * {@link ConnectionService}.
+     * <p>
+     * These extras changes can originate from Telecom itself, or from an {@link InCallService} via
+     * {@link android.telecom.Call#putExtras(Bundle)}, and
+     * {@link Call#removeExtras(List)}.
+     *
+     * @param extras The new extras bundle.
+     */
+    public void onExtrasChanged(Bundle extras) {}
+
+    /**
+     * Handles a change to extras received from Telecom.
+     *
+     * @param extras The new extras.
+     * @hide
+     */
+    final void handleExtrasChanged(Bundle extras) {
+        mExtras = extras;
+        onExtrasChanged(mExtras);
+    }
 }
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 51a6588..310c957 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -20,6 +20,7 @@
 import com.android.internal.telecom.IVideoCallback;
 import com.android.internal.telecom.IVideoProvider;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.hardware.camera2.CameraManager;
@@ -30,6 +31,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.util.ArraySet;
 import android.view.Surface;
 
 import java.util.ArrayList;
@@ -96,7 +98,7 @@
      * The state of an external connection which is in the process of being pulled from a remote
      * device to the local device.
      * <p>
-     * A connection can only be in this state if the {@link #CAPABILITY_IS_EXTERNAL_CALL} and
+     * A connection can only be in this state if the {@link #PROPERTY_IS_EXTERNAL_CALL} property and
      * {@link #CAPABILITY_CAN_PULL_CALL} capability bits are set on the connection.
      */
     public static final int STATE_PULLING_CALL = 7;
@@ -192,31 +194,28 @@
     public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
 
     /**
-     * Whether the call is a generic conference, where we do not know the precise state of
-     * participants in the conference (eg. on CDMA).
-     *
+     * Un-used.
      * @hide
      */
-    public static final int CAPABILITY_GENERIC_CONFERENCE = 0x00004000;
+    public static final int CAPABILITY_UNUSED_2 = 0x00004000;
 
     /**
-     * Connection is using high definition audio.
+     * Un-used.
      * @hide
      */
-    public static final int CAPABILITY_HIGH_DEF_AUDIO = 0x00008000;
+    public static final int CAPABILITY_UNUSED_3 = 0x00008000;
 
     /**
-     * Connection is using WIFI.
+     * Un-used.
      * @hide
      */
-    public static final int CAPABILITY_WIFI = 0x00010000;
+    public static final int CAPABILITY_UNUSED_4 = 0x00010000;
 
     /**
-     * Indicates that the current device callback number should be shown.
-     *
+     * Un-used.
      * @hide
      */
-    public static final int CAPABILITY_SHOW_CALLBACK_NUMBER = 0x00020000;
+    public static final int CAPABILITY_UNUSED_5 = 0x00020000;
 
     /**
      * Speed up audio setup for MT call.
@@ -279,32 +278,64 @@
     public static final int CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO = 0x00800000;
 
     /**
+     * When set for an external connection, indicates that this {@code Connection} can be pulled
+     * from a remote device to the current device.
+     * <p>
+     * Should only be set on a {@code Connection} where {@link #PROPERTY_IS_EXTERNAL_CALL}
+     * is set.
+     */
+    public static final int CAPABILITY_CAN_PULL_CALL = 0x01000000;
+
+    //**********************************************************************************************
+    // Next CAPABILITY value: 0x02000000
+    //**********************************************************************************************
+
+    /**
+     * Indicates that the current device callback number should be shown.
+     *
+     * @hide
+     */
+    public static final int PROPERTY_SHOW_CALLBACK_NUMBER = 1<<0;
+
+    /**
+     * Whether the call is a generic conference, where we do not know the precise state of
+     * participants in the conference (eg. on CDMA).
+     *
+     * @hide
+     */
+    public static final int PROPERTY_GENERIC_CONFERENCE = 1<<1;
+
+    /**
+     * Connection is using high definition audio.
+     * @hide
+     */
+    public static final int PROPERTY_HIGH_DEF_AUDIO = 1<<2;
+
+    /**
+     * Connection is using WIFI.
+     * @hide
+     */
+    public static final int PROPERTY_WIFI = 1<<3;
+
+    /**
      * When set, indicates that the {@code Connection} does not actually exist locally for the
      * {@link ConnectionService}.
      * <p>
      * Consider, for example, a scenario where a user has two devices with the same phone number.
      * When a user places a call on one devices, the telephony stack can represent that call on the
      * other device by adding is to the {@link ConnectionService} with the
-     * {@code CAPABILITY_IS_EXTERNAL_CALL} capability set.
+     * {@link #PROPERTY_IS_EXTERNAL_CALL} capability set.
      * <p>
      * An {@link ConnectionService} should not assume that all {@link InCallService}s will handle
      * external connections.  Only those {@link InCallService}s which have the
      * {@link TelecomManager#METADATA_INCLUDE_EXTERNAL_CALLS} metadata set to {@code true} in its
      * manifest will see external connections.
      */
-    public static final int CAPABILITY_IS_EXTERNAL_CALL = 0x01000000;
+    public static final int PROPERTY_IS_EXTERNAL_CALL = 1<<4;
 
-    /**
-     * When set for an external connection, indicates that this {@code Connection} can be pulled
-     * from a remote device to the current device.
-     * <p>
-     * Should only be set on a {@code Connection} where {@link #CAPABILITY_IS_EXTERNAL_CALL}
-     * is set.
-     */
-    public static final int CAPABILITY_CAN_PULL_CALL = 0x02000000;
 
     //**********************************************************************************************
-    // Next CAPABILITY value: 0x04000000
+    // Next PROPERTY value: 1<<5
     //**********************************************************************************************
 
     /**
@@ -452,18 +483,6 @@
         if (can(capabilities, CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO)) {
             builder.append(" CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO");
         }
-        if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
-            builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
-        }
-        if (can(capabilities, CAPABILITY_WIFI)) {
-            builder.append(" CAPABILITY_WIFI");
-        }
-        if (can(capabilities, CAPABILITY_GENERIC_CONFERENCE)) {
-            builder.append(" CAPABILITY_GENERIC_CONFERENCE");
-        }
-        if (can(capabilities, CAPABILITY_SHOW_CALLBACK_NUMBER)) {
-            builder.append(" CAPABILITY_SHOW_CALLBACK_NUMBER");
-        }
         if (can(capabilities, CAPABILITY_SPEED_UP_MT_AUDIO)) {
             builder.append(" CAPABILITY_SPEED_UP_MT_AUDIO");
         }
@@ -479,9 +498,6 @@
         if (can(capabilities, CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION)) {
             builder.append(" CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION");
         }
-        if (can(capabilities, CAPABILITY_IS_EXTERNAL_CALL)) {
-            builder.append(" CAPABILITY_IS_EXTERNAL_CALL");
-        }
         if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) {
             builder.append(" CAPABILITY_CAN_PULL_CALL");
         }
@@ -490,6 +506,34 @@
         return builder.toString();
     }
 
+    public static String propertiesToString(int properties) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("[Properties:");
+
+        if (can(properties, PROPERTY_SHOW_CALLBACK_NUMBER)) {
+            builder.append(" PROPERTY_SHOW_CALLBACK_NUMBER");
+        }
+
+        if (can(properties, PROPERTY_HIGH_DEF_AUDIO)) {
+            builder.append(" PROPERTY_HIGH_DEF_AUDIO");
+        }
+
+        if (can(properties, PROPERTY_WIFI)) {
+            builder.append(" PROPERTY_WIFI");
+        }
+
+        if (can(properties, PROPERTY_GENERIC_CONFERENCE)) {
+            builder.append(" PROPERTY_GENERIC_CONFERENCE");
+        }
+
+        if (can(properties, PROPERTY_IS_EXTERNAL_CALL)) {
+            builder.append(" PROPERTY_IS_EXTERNAL_CALL");
+        }
+
+        builder.append("]");
+        return builder.toString();
+    }
+
     /** @hide */
     public abstract static class Listener {
         public void onStateChanged(Connection c, int state) {}
@@ -503,6 +547,7 @@
         public void onRingbackRequested(Connection c, boolean ringback) {}
         public void onDestroyed(Connection c) {}
         public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
+        public void onConnectionPropertiesChanged(Connection c, int properties) {}
         public void onVideoProviderChanged(
                 Connection c, VideoProvider videoProvider) {}
         public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
@@ -516,6 +561,7 @@
         public void onConferenceStarted() {}
         public void onConferenceMergeFailed(Connection c) {}
         public void onExtrasChanged(Connection c, Bundle extras) {}
+        public void onExtrasRemoved(Connection c, List<String> keys) {}
         public void onConnectionEvent(Connection c, String event, Bundle extras) {}
     }
 
@@ -1172,6 +1218,7 @@
     private int mCallerDisplayNamePresentation;
     private boolean mRingbackRequested = false;
     private int mConnectionCapabilities;
+    private int mConnectionProperties;
     private VideoProvider mVideoProvider;
     private boolean mAudioModeIsVoip;
     private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
@@ -1183,6 +1230,13 @@
     private Bundle mExtras;
 
     /**
+     * Tracks the key set for the extras bundle provided on the last invocation of
+     * {@link #setExtras(Bundle)}.  Used so that on subsequent invocations we can remove any extras
+     * keys which were set previously but are no longer present in the replacement Bundle.
+     */
+    private Set<String> mPreviousExtraKeys;
+
+    /**
      * Create a new Connection.
      */
     public Connection() {}
@@ -1318,6 +1372,17 @@
     }
 
     /**
+     * Returns the extras associated with this connection.
+     * <p>
+     * Extras should be updated using {@link #putExtras(Bundle)}.
+     * <p>
+     * Telecom or an {@link InCallService} can also update the extras via
+     * {@link android.telecom.Call#putExtras(Bundle)}, and
+     * {@link Call#removeExtras(List)}.
+     * <p>
+     * The connection is notified of changes to the extras made by Telecom or an
+     * {@link InCallService} by {@link #onExtrasChanged(Bundle)}.
+     *
      * @return The extras associated with this connection.
      */
     public final Bundle getExtras() {
@@ -1418,6 +1483,13 @@
     }
 
     /**
+     * Returns the connection's properties, as a bit mask of the {@code PROPERTY_*} constants.
+     */
+    public final int getConnectionProperties() {
+        return mConnectionProperties;
+    }
+
+    /**
      * Sets the value of the {@link #getAddress()} property.
      *
      * @param address The new address.
@@ -1614,6 +1686,21 @@
     }
 
     /**
+     * Sets the connection's properties as a bit mask of the {@code PROPERTY_*} constants.
+     *
+     * @param connectionProperties The new connection properties.
+     */
+    public final void setConnectionProperties(int connectionProperties) {
+        checkImmutable();
+        if (mConnectionProperties != connectionProperties) {
+            mConnectionProperties = connectionProperties;
+            for (Listener l : mListeners) {
+                l.onConnectionPropertiesChanged(this, mConnectionProperties);
+            }
+        }
+    }
+
+    /**
      * Tears down the Connection object.
      */
     public final void destroy() {
@@ -1777,21 +1864,133 @@
     }
 
     /**
-     * Set some extras that can be associated with this {@code Connection}. No assumptions should
-     * be made as to how an In-Call UI or service will handle these extras.
+     * Set some extras that can be associated with this {@code Connection}.
+     * <p>
+     * New or existing keys are replaced in the {@code Connection} extras.  Keys which are no longer
+     * in the new extras, but were present the last time {@code setExtras} was called are removed.
+     * <p>
+     * No assumptions should be made as to how an In-Call UI or service will handle these extras.
      * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
      *
      * @param extras The extras associated with this {@code Connection}.
+     * @deprecated Use {@link #putExtras(Bundle)} to add extras.  Use {@link #removeExtras(List)}
+     * to remove extras.
      */
     public final void setExtras(@Nullable Bundle extras) {
         checkImmutable();
-        mExtras = extras;
+
+        // Add/replace any new or changed extras values.
+        putExtras(extras);
+
+        // If we have used "setExtras" in the past, compare the key set from the last invocation to
+        // the current one and remove any keys that went away.
+        if (mPreviousExtraKeys != null) {
+            List<String> toRemove = new ArrayList<String>();
+            for (String oldKey : mPreviousExtraKeys) {
+                if (!extras.containsKey(oldKey)) {
+                    toRemove.add(oldKey);
+                }
+            }
+            if (!toRemove.isEmpty()) {
+                removeExtras(toRemove);
+            }
+        }
+
+        // Track the keys the last time set called setExtras.  This way, the next time setExtras is
+        // called we can see if the caller has removed any extras values.
+        if (mPreviousExtraKeys == null) {
+            mPreviousExtraKeys = new ArraySet<String>();
+        }
+        mPreviousExtraKeys.clear();
+        mPreviousExtraKeys.addAll(extras.keySet());
+    }
+
+    /**
+     * Adds some extras to this {@code Connection}.  Existing keys are replaced and new ones are
+     * added.
+     * <p>
+     * No assumptions should be made as to how an In-Call UI or service will handle these extras.
+     * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
+     *
+     * @param extras The extras to add.
+     */
+    public final void putExtras(@NonNull Bundle extras) {
+        checkImmutable();
+        if (extras == null) {
+            return;
+        }
+
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putAll(extras);
+
         for (Listener l : mListeners) {
             l.onExtrasChanged(this, extras);
         }
     }
 
     /**
+     * Adds a boolean extra to this {@code Connection}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, boolean value) {
+        Bundle newExtras = new Bundle();
+        newExtras.putBoolean(key, value);
+        putExtras(newExtras);
+    }
+
+    /**
+     * Adds an integer extra to this {@code Connection}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, int value) {
+        Bundle newExtras = new Bundle();
+        newExtras.putInt(key, value);
+        putExtras(newExtras);
+    }
+
+    /**
+     * Adds a string extra to this {@code Connection}.
+     *
+     * @param key The extra key.
+     * @param value The value.
+     * @hide
+     */
+    public final void putExtra(String key, String value) {
+        Bundle newExtras = new Bundle();
+        newExtras.putString(key, value);
+        putExtras(newExtras);
+    }
+
+    /**
+     * Removes an extra from this {@code Connection}.
+     *
+     * @param keys The key of the extra key to remove.
+     */
+    public final void removeExtras(List<String> keys) {
+        if (mExtras != null) {
+            for (String key : keys) {
+                mExtras.remove(key);
+            }
+
+            if (mExtras.size() == 0) {
+                mExtras = null;
+            }
+        }
+
+        for (Listener l : mListeners) {
+            l.onExtrasRemoved(this, keys);
+        }
+    }
+
+    /**
      * Notifies this Connection that the {@link #getAudioState()} property has a new value.
      *
      * @param state The new connection audio state.
@@ -1909,10 +2108,10 @@
      * The {@link InCallService} issues a request to pull an external call to the local device via
      * {@link Call#pullExternalCall()}.
      * <p>
-     * For a Connection to be pulled, both the {@link Connection#CAPABILITY_CAN_PULL_CALL} and
-     * {@link Connection#CAPABILITY_IS_EXTERNAL_CALL} capability bits must be set.
+     * For a Connection to be pulled, both the {@link Connection#CAPABILITY_CAN_PULL_CALL}
+     * capability and {@link Connection#PROPERTY_IS_EXTERNAL_CALL} property bits must be set.
      * <p>
-     * For more information on external calls, see {@link Connection#CAPABILITY_IS_EXTERNAL_CALL}.
+     * For more information on external calls, see {@link Connection#PROPERTY_IS_EXTERNAL_CALL}.
      */
     public void onPullExternalCall() {}
 
@@ -1928,6 +2127,18 @@
      */
     public void onCallEvent(String event, Bundle extras) {}
 
+    /**
+     * Notifies this {@link Connection} of a change to the extras made outside the
+     * {@link ConnectionService}.
+     * <p>
+     * These extras changes can originate from Telecom itself, or from an {@link InCallService} via
+     * the {@link android.telecom.Call#putExtras(Bundle)} and
+     * {@link Call#removeExtras(List)}.
+     *
+     * @param extras The new extras bundle.
+     */
+    public void onExtrasChanged(Bundle extras) {}
+
     static String toLogSafePhoneNumber(String number) {
         // For unknown number, log empty string.
         if (number == null) {
@@ -2048,6 +2259,17 @@
     }
 
     /**
+     * Handles a change to extras received from Telecom.
+     *
+     * @param extras The new extras.
+     * @hide
+     */
+    final void handleExtrasChanged(Bundle extras) {
+        mExtras = extras;
+        onExtrasChanged(mExtras);
+    }
+
+    /**
      * Notifies listeners that the merge request failed.
      *
      * @hide
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index d18b317..4cab7f0 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -105,6 +105,7 @@
     private static final int MSG_SILENCE = 21;
     private static final int MSG_PULL_EXTERNAL_CALL = 22;
     private static final int MSG_SEND_CALL_EVENT = 23;
+    private static final int MSG_ON_EXTRAS_CHANGED = 24;
 
     private static Connection sNullConnection;
 
@@ -261,6 +262,14 @@
             args.arg3 = extras;
             mHandler.obtainMessage(MSG_SEND_CALL_EVENT, args).sendToTarget();
         }
+
+        @Override
+        public void onExtrasChanged(String callId, Bundle extras) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = extras;
+            mHandler.obtainMessage(MSG_ON_EXTRAS_CHANGED, args).sendToTarget();
+        }
     };
 
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -414,6 +423,17 @@
                     }
                     break;
                 }
+                case MSG_ON_EXTRAS_CHANGED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        String callId = (String) args.arg1;
+                        Bundle extras = (Bundle) args.arg2;
+                        handleExtrasChanged(callId, extras);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
                 default:
                     break;
             }
@@ -475,6 +495,16 @@
         }
 
         @Override
+        public void onConnectionPropertiesChanged(
+                Conference conference,
+                int connectionProperties) {
+            String id = mIdByConference.get(conference);
+            Log.d(this, "call capabilities: conference: %s",
+                    Connection.propertiesToString(connectionProperties));
+            mAdapter.setConnectionProperties(id, connectionProperties);
+        }
+
+        @Override
         public void onVideoStateChanged(Conference c, int videoState) {
             String id = mIdByConference.get(c);
             Log.d(this, "onVideoStateChanged set video state %d", videoState);
@@ -492,13 +522,25 @@
         @Override
         public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {
             String id = mIdByConference.get(conference);
-            mAdapter.setStatusHints(id, statusHints);
+            if (id != null) {
+                mAdapter.setStatusHints(id, statusHints);
+            }
         }
 
         @Override
-        public void onExtrasChanged(Conference conference, Bundle extras) {
-            String id = mIdByConference.get(conference);
-            mAdapter.setExtras(id, extras);
+        public void onExtrasChanged(Conference c, Bundle extras) {
+            String id = mIdByConference.get(c);
+            if (id != null) {
+                mAdapter.putExtras(id, extras);
+            }
+        }
+
+        @Override
+        public void onExtrasRemoved(Conference c, List<String> keys) {
+            String id = mIdByConference.get(c);
+            if (id != null) {
+                mAdapter.removeExtras(id, keys);
+            }
         }
     };
 
@@ -591,6 +633,14 @@
         }
 
         @Override
+        public void onConnectionPropertiesChanged(Connection c, int properties) {
+            String id = mIdByConnection.get(c);
+            Log.d(this, "properties: parcelableconnection: %s",
+                    Connection.propertiesToString(properties));
+            mAdapter.setConnectionProperties(id, properties);
+        }
+
+        @Override
         public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) {
             String id = mIdByConnection.get(c);
             Log.d(this, "onVideoProviderChanged: Connection: %s, VideoProvider: %s", c,
@@ -639,12 +689,20 @@
         }
 
         @Override
-        public void onExtrasChanged(Connection connection, Bundle extras) {
-            String id = mIdByConnection.get(connection);
+        public void onExtrasChanged(Connection c, Bundle extras) {
+            String id = mIdByConnection.get(c);
             if (id != null) {
-                mAdapter.setExtras(id, extras);
+                mAdapter.putExtras(id, extras);
             }
         }
+        
+        public void onExtrasRemoved(Connection c, List<String> keys) {
+            String id = mIdByConnection.get(c);
+            if (id != null) {
+                mAdapter.removeExtras(id, keys);
+            }
+        }
+
 
         @Override
         public void onConnectionEvent(Connection connection, String event, Bundle extras) {
@@ -700,10 +758,11 @@
 
         Uri address = connection.getAddress();
         String number = address == null ? "null" : address.getSchemeSpecificPart();
-        Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s",
+        Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
                 Connection.toLogSafePhoneNumber(number),
                 Connection.stateToString(connection.getState()),
-                Connection.capabilitiesToString(connection.getConnectionCapabilities()));
+                Connection.capabilitiesToString(connection.getConnectionCapabilities()),
+                Connection.propertiesToString(connection.getConnectionProperties()));
 
         Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
         mAdapter.handleCreateConnectionComplete(
@@ -713,6 +772,7 @@
                         request.getAccountHandle(),
                         connection.getState(),
                         connection.getConnectionCapabilities(),
+                        connection.getConnectionProperties(),
                         connection.getAddress(),
                         connection.getAddressPresentation(),
                         connection.getCallerDisplayName(),
@@ -929,6 +989,27 @@
 
     }
 
+    /**
+     * Notifies a {@link Connection} or {@link Conference} of a change to the extras from Telecom.
+     * <p>
+     * These extra changes can originate from Telecom itself, or from an {@link InCallService} via
+     * the {@link android.telecom.Call#putExtra(String, boolean)},
+     * {@link android.telecom.Call#putExtra(String, int)},
+     * {@link android.telecom.Call#putExtra(String, String)},
+     * {@link Call#removeExtras(List)}.
+     *
+     * @param callId The ID of the call receiving the event.
+     * @param extras The new extras bundle.
+     */
+    private void handleExtrasChanged(String callId, Bundle extras) {
+        Log.d(this, "handleExtrasChanged(%s, %s)", callId, extras);
+        if (mConnectionById.containsKey(callId)) {
+            findConnectionForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
+        } else if (mConferenceById.containsKey(callId)) {
+            findConferenceForAction(callId, "handleExtrasChanged").handleExtrasChanged(extras);
+        }
+    }
+
     private void onPostDialContinue(String callId, boolean proceed) {
         Log.d(this, "onPostDialContinue(%s)", callId);
         findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
@@ -1049,6 +1130,7 @@
                     conference.getPhoneAccountHandle(),
                     conference.getState(),
                     conference.getConnectionCapabilities(),
+                    conference.getConnectionProperties(),
                     connectionIds,
                     conference.getVideoProvider() == null ?
                             null : conference.getVideoProvider().getInterface(),
@@ -1089,6 +1171,7 @@
                     phoneAccountHandle,
                     connection.getState(),
                     connection.getConnectionCapabilities(),
+                    connection.getConnectionProperties(),
                     connection.getAddress(),
                     connection.getAddressPresentation(),
                     connection.getCallerDisplayName(),
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index e91128f..c8cd3c0 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -196,6 +196,15 @@
         }
     }
 
+    void setConnectionProperties(String callId, int properties) {
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                adapter.setConnectionProperties(callId, properties);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     /**
      * Indicates whether or not the specified call is currently conferenced into the specified
      * conference call.
@@ -398,16 +407,88 @@
     }
 
     /**
-     * Sets extras associated with a connection.
+     * Adds some extras associated with a {@code Connection}.
      *
      * @param callId The unique ID of the call.
-     * @param extras The extras to associate with this call.
+     * @param extras The extras to add.
      */
-    void setExtras(String callId, Bundle extras) {
-        Log.v(this, "setExtras: %s", extras);
+    void putExtras(String callId, Bundle extras) {
+        Log.v(this, "putExtras: %s", callId);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setExtras(callId, extras);
+                adapter.putExtras(callId, extras);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    /**
+     * Adds an extra associated with a {@code Connection}.
+     *
+     * @param callId The unique ID of the call.
+     * @param key The extra key.
+     * @param value The extra value.
+     */
+    void putExtra(String callId, String key, boolean value) {
+        Log.v(this, "putExtra: %s %s=%b", callId, key, value);
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                Bundle bundle = new Bundle();
+                bundle.putBoolean(key, value);
+                adapter.putExtras(callId, bundle);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    /**
+     * Adds an extra associated with a {@code Connection}.
+     *
+     * @param callId The unique ID of the call.
+     * @param key The extra key.
+     * @param value The extra value.
+     */
+    void putExtra(String callId, String key, int value) {
+        Log.v(this, "putExtra: %s %s=%d", callId, key, value);
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                Bundle bundle = new Bundle();
+                bundle.putInt(key, value);
+                adapter.putExtras(callId, bundle);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    /**
+     * Adds an extra associated with a {@code Connection}.
+     *
+     * @param callId The unique ID of the call.
+     * @param key The extra key.
+     * @param value The extra value.
+     */
+    void putExtra(String callId, String key, String value) {
+        Log.v(this, "putExtra: %s %s=%s", callId, key, value);
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                Bundle bundle = new Bundle();
+                bundle.putString(key, value);
+                adapter.putExtras(callId, bundle);
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
+    /**
+     * Removes extras associated with a {@code Connection}.
+     *  @param callId The unique ID of the call.
+     * @param keys The extra keys to remove.
+     */
+    void removeExtras(String callId, List<String> keys) {
+        Log.v(this, "removeExtras: %s %s", callId, keys);
+        for (IConnectionServiceAdapter adapter : mAdapters) {
+            try {
+                adapter.removeExtras(callId, keys);
             } catch (RemoteException ignored) {
             }
         }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 4b15e54..bf28feb 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -61,8 +61,10 @@
     private static final int MSG_ADD_EXISTING_CONNECTION = 21;
     private static final int MSG_ON_POST_DIAL_CHAR = 22;
     private static final int MSG_SET_CONFERENCE_MERGE_FAILED = 23;
-    private static final int MSG_SET_EXTRAS = 24;
-    private static final int MSG_ON_CONNECTION_EVENT = 25;
+    private static final int MSG_PUT_EXTRAS = 24;
+    private static final int MSG_REMOVE_EXTRAS = 25;
+    private static final int MSG_ON_CONNECTION_EVENT = 26;
+    private static final int MSG_SET_CONNECTION_PROPERTIES = 27;
 
     private final IConnectionServiceAdapter mDelegate;
 
@@ -117,6 +119,9 @@
                 case MSG_SET_CONNECTION_CAPABILITIES:
                     mDelegate.setConnectionCapabilities((String) msg.obj, msg.arg1);
                     break;
+                case MSG_SET_CONNECTION_PROPERTIES:
+                    mDelegate.setConnectionProperties((String) msg.obj, msg.arg1);
+                    break;
                 case MSG_SET_IS_CONFERENCED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
@@ -233,10 +238,19 @@
                     }
                     break;
                 }
-                case MSG_SET_EXTRAS: {
+                case MSG_PUT_EXTRAS: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setExtras((String) args.arg1, (Bundle) args.arg2);
+                        mDelegate.putExtras((String) args.arg1, (Bundle) args.arg2);
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
+                case MSG_REMOVE_EXTRAS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        mDelegate.removeExtras((String) args.arg1, (List<String>) args.arg2);
                     } finally {
                         args.recycle();
                     }
@@ -312,6 +326,13 @@
         }
 
         @Override
+        public void setConnectionProperties(String connectionId, int connectionProperties) {
+            mHandler.obtainMessage(
+                    MSG_SET_CONNECTION_PROPERTIES, connectionProperties, 0, connectionId)
+                    .sendToTarget();
+        }
+
+        @Override
         public void setConferenceMergeFailed(String callId) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = callId;
@@ -425,11 +446,19 @@
         }
 
         @Override
-        public final void setExtras(String connectionId, Bundle extras) {
+        public final void putExtras(String connectionId, Bundle extras) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = extras;
-            mHandler.obtainMessage(MSG_SET_EXTRAS, args).sendToTarget();
+            mHandler.obtainMessage(MSG_PUT_EXTRAS, args).sendToTarget();
+        }
+
+        @Override
+        public final void removeExtras(String connectionId, List<String> keys) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = connectionId;
+            args.arg2 = keys;
+            mHandler.obtainMessage(MSG_REMOVE_EXTRAS, args).sendToTarget();
         }
 
         @Override
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index 52ef4a7..3f270d9 100644
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -21,6 +21,8 @@
 
 import com.android.internal.telecom.IInCallAdapter;
 
+import java.util.List;
+
 /**
  * Receives commands from {@link InCallService} implementations which should be executed by
  * Telecom. When Telecom binds to a {@link InCallService}, an instance of this class is given to
@@ -278,6 +280,79 @@
     }
 
     /**
+     * Intructs Telecom to add extras to a call.
+     *
+     * @param callId The callId to add the extras to.
+     * @param extras The extras.
+     */
+    public void putExtras(String callId, Bundle extras) {
+        try {
+            mAdapter.putExtras(callId, extras);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
+     * Intructs Telecom to add an extra to a call.
+     *
+     * @param callId The callId to add the extras to.
+     * @param key The extra key.
+     * @param value The extra value.
+     */
+    public void putExtra(String callId, String key, boolean value) {
+        try {
+            Bundle bundle = new Bundle();
+            bundle.putBoolean(key, value);
+            mAdapter.putExtras(callId, bundle);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
+     * Intructs Telecom to add an extra to a call.
+     *
+     * @param callId The callId to add the extras to.
+     * @param key The extra key.
+     * @param value The extra value.
+     */
+    public void putExtra(String callId, String key, int value) {
+        try {
+            Bundle bundle = new Bundle();
+            bundle.putInt(key, value);
+            mAdapter.putExtras(callId, bundle);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
+     * Intructs Telecom to add an extra to a call.
+     *
+     * @param callId The callId to add the extras to.
+     * @param key The extra key.
+     * @param value The extra value.
+     */
+    public void putExtra(String callId, String key, String value) {
+        try {
+            Bundle bundle = new Bundle();
+            bundle.putString(key, value);
+            mAdapter.putExtras(callId, bundle);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
+     * Intructs Telecom to remove extras from a call.
+     * @param callId The callId to remove the extras from.
+     * @param keys The extra keys to remove.
+     */
+    public void removeExtras(String callId, List<String> keys) {
+        try {
+            mAdapter.removeExtras(callId, keys);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    /**
      * Instructs Telecom to turn the proximity sensor on.
      */
     public void turnProximitySensorOn() {
diff --git a/telecomm/java/android/telecom/ParcelableConference.java b/telecomm/java/android/telecom/ParcelableConference.java
index 870f5ee..f5689d8 100644
--- a/telecomm/java/android/telecom/ParcelableConference.java
+++ b/telecomm/java/android/telecom/ParcelableConference.java
@@ -34,6 +34,7 @@
     private PhoneAccountHandle mPhoneAccount;
     private int mState;
     private int mConnectionCapabilities;
+    private int mConnectionProperties;
     private List<String> mConnectionIds;
     private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
     private final IVideoProvider mVideoProvider;
@@ -45,6 +46,7 @@
             PhoneAccountHandle phoneAccount,
             int state,
             int connectionCapabilities,
+            int connectionProperties,
             List<String> connectionIds,
             IVideoProvider videoProvider,
             int videoState,
@@ -54,6 +56,7 @@
         mPhoneAccount = phoneAccount;
         mState = state;
         mConnectionCapabilities = connectionCapabilities;
+        mConnectionProperties = connectionProperties;
         mConnectionIds = connectionIds;
         mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
         mVideoProvider = videoProvider;
@@ -72,6 +75,8 @@
                 .append(Connection.stateToString(mState))
                 .append(", capabilities: ")
                 .append(Connection.capabilitiesToString(mConnectionCapabilities))
+                .append(", properties: ")
+                .append(Connection.propertiesToString(mConnectionProperties))
                 .append(", connectTime: ")
                 .append(mConnectTimeMillis)
                 .append(", children: ")
@@ -95,6 +100,10 @@
         return mConnectionCapabilities;
     }
 
+    public int getConnectionProperties() {
+        return mConnectionProperties;
+    }
+
     public List<String> getConnectionIds() {
         return mConnectionIds;
     }
@@ -134,9 +143,11 @@
             int videoState = source.readInt();
             StatusHints statusHints = source.readParcelable(classLoader);
             Bundle extras = source.readBundle(classLoader);
+            int properties = source.readInt();
 
-            return new ParcelableConference(phoneAccount, state, capabilities, connectionIds,
-                    videoCallProvider, videoState, connectTimeMillis, statusHints, extras);
+            return new ParcelableConference(phoneAccount, state, capabilities, properties,
+                    connectionIds, videoCallProvider, videoState, connectTimeMillis, statusHints,
+                    extras);
         }
 
         @Override
@@ -164,5 +175,6 @@
         destination.writeInt(mVideoState);
         destination.writeParcelable(mStatusHints, 0);
         destination.writeBundle(mExtras);
+        destination.writeInt(mConnectionProperties);
     }
 }
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index ce51c96..540f388 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -36,6 +36,7 @@
     private final PhoneAccountHandle mPhoneAccount;
     private final int mState;
     private final int mConnectionCapabilities;
+    private final int mConnectionProperties;
     private final Uri mAddress;
     private final int mAddressPresentation;
     private final String mCallerDisplayName;
@@ -55,6 +56,7 @@
             PhoneAccountHandle phoneAccount,
             int state,
             int capabilities,
+            int properties,
             Uri address,
             int addressPresentation,
             String callerDisplayName,
@@ -71,6 +73,7 @@
         mPhoneAccount = phoneAccount;
         mState = state;
         mConnectionCapabilities = capabilities;
+        mConnectionProperties = properties;
         mAddress = address;
         mAddressPresentation = addressPresentation;
         mCallerDisplayName = callerDisplayName;
@@ -94,11 +97,26 @@
         return mState;
     }
 
-    // Bit mask of actions a call supports, values are defined in {@link CallCapabilities}.
+    /**
+     * Returns the current connection capabilities bit-mask.  Connection capabilities are defined as
+     * {@code CAPABILITY_*} constants in {@link Connection}.
+     *
+     * @return Bit-mask containing capabilities of the connection.
+     */
     public int getConnectionCapabilities() {
         return mConnectionCapabilities;
     }
 
+    /**
+     * Returns the current connection properties bit-mask.  Connection properties are defined as
+     * {@code PROPERTY_*} constants in {@link Connection}.
+     *
+     * @return Bit-mask containing properties of the connection.
+     */
+    public int getConnectionProperties() {
+        return mConnectionProperties;
+    }
+
     public Uri getHandle() {
         return mAddress;
     }
@@ -160,6 +178,8 @@
                 .append(mState)
                 .append(", capabilities:")
                 .append(Connection.capabilitiesToString(mConnectionCapabilities))
+                .append(", properties:")
+                .append(Connection.propertiesToString(mConnectionProperties))
                 .append(", extras:")
                 .append(mExtras)
                 .toString();
@@ -189,11 +209,13 @@
             List<String> conferenceableConnectionIds = new ArrayList<>();
             source.readStringList(conferenceableConnectionIds);
             Bundle extras = Bundle.setDefusable(source.readBundle(classLoader), true);
+            int properties = source.readInt();
 
             return new ParcelableConnection(
                     phoneAccount,
                     state,
                     capabilities,
+                    properties,
                     address,
                     addressPresentation,
                     callerDisplayName,
@@ -241,5 +263,6 @@
         destination.writeParcelable(mDisconnectCause, 0);
         destination.writeStringList(mConferenceableConnectionIds);
         destination.writeBundle(mExtras);
+        destination.writeInt(mConnectionProperties);
     }
 }
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index ae5cd46..943da6d 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -92,6 +92,18 @@
                 int connectionCapabilities) {}
 
         /**
+         * Indicates that the call properties of this {@code RemoteConference} have changed.
+         * See {@link #getConnectionProperties()}.
+         *
+         * @param conference The {@code RemoteConference} invoking this method.
+         * @param connectionProperties The new properties of the {@code RemoteConference}.
+         */
+        public void onConnectionPropertiesChanged(
+                RemoteConference conference,
+                int connectionProperties) {}
+
+
+        /**
          * Invoked when the set of {@link RemoteConnection}s which can be added to this conference
          * call have changed.
          *
@@ -133,6 +145,7 @@
     private int mState = Connection.STATE_NEW;
     private DisconnectCause mDisconnectCause;
     private int mConnectionCapabilities;
+    private int mConnectionProperties;
     private Bundle mExtras;
 
     /** @hide */
@@ -244,6 +257,24 @@
     }
 
     /** @hide */
+    void setConnectionProperties(final int connectionProperties) {
+        if (mConnectionProperties != connectionProperties) {
+            mConnectionProperties = connectionProperties;
+            for (CallbackRecord<Callback> record : mCallbackRecords) {
+                final RemoteConference conference = this;
+                final Callback callback = record.getCallback();
+                record.getHandler().post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onConnectionPropertiesChanged(
+                                conference, mConnectionProperties);
+                    }
+                });
+            }
+        }
+    }
+
+    /** @hide */
     void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
         mConferenceableConnections.clear();
         mConferenceableConnections.addAll(conferenceableConnections);
@@ -279,15 +310,35 @@
     }
 
     /** @hide */
-    void setExtras(final Bundle extras) {
-        mExtras = extras;
+    void putExtras(final Bundle extras) {
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putAll(extras);
+
+        notifyExtrasChanged();
+    }
+
+    /** @hide */
+    void removeExtras(List<String> keys) {
+        if (mExtras == null || keys == null || keys.isEmpty()) {
+            return;
+        }
+        for (String key : keys) {
+            mExtras.remove(key);
+        }
+
+        notifyExtrasChanged();
+    }
+
+    private void notifyExtrasChanged() {
         for (CallbackRecord<Callback> record : mCallbackRecords) {
             final RemoteConference conference = this;
             final Callback callback = record.getCallback();
             record.getHandler().post(new Runnable() {
                 @Override
                 public void run() {
-                    callback.onExtrasChanged(conference, extras);
+                    callback.onExtrasChanged(conference, mExtras);
                 }
             });
         }
@@ -322,6 +373,16 @@
     }
 
     /**
+     * Returns the properties of the conference. See {@code PROPERTY_*} constants in class
+     * {@link Connection} for valid values.
+     *
+     * @return A bitmask of the properties of the conference call.
+     */
+    public final int getConnectionProperties() {
+        return mConnectionProperties;
+    }
+
+    /**
      * Obtain the extras associated with this {@code RemoteConnection}.
      *
      * @return The extras for this connection.
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 5b602eb..dc8eaf6 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -90,6 +90,17 @@
                 int connectionCapabilities) {}
 
         /**
+         * Indicates that the call properties of this {@code RemoteConnection} have changed.
+         * See {@link #getConnectionProperties()}.
+         *
+         * @param connection The {@code RemoteConnection} invoking this method.
+         * @param connectionProperties The new properties of the {@code RemoteConnection}.
+         */
+        public void onConnectionPropertiesChanged(
+                RemoteConnection connection,
+                int connectionProperties) {}
+
+        /**
          * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a
          * pause character. This causes the post-dial signals to stop pending user confirmation. An
          * implementation should present this choice to the user and invoke
@@ -588,6 +599,7 @@
     private boolean mRingbackRequested;
     private boolean mConnected;
     private int mConnectionCapabilities;
+    private int mConnectionProperties;
     private int mVideoState;
     private VideoProvider mVideoProvider;
     private boolean mIsVoipAudioMode;
@@ -624,6 +636,7 @@
         mDisconnectCause = connection.getDisconnectCause();
         mRingbackRequested = connection.isRingbackRequested();
         mConnectionCapabilities = connection.getConnectionCapabilities();
+        mConnectionProperties = connection.getConnectionProperties();
         mVideoState = connection.getVideoState();
         mVideoProvider = new RemoteConnection.VideoProvider(connection.getVideoProvider());
         mIsVoipAudioMode = connection.getIsVoipAudioMode();
@@ -719,6 +732,16 @@
     }
 
     /**
+     * Obtains the properties of this {@code RemoteConnection}.
+     *
+     * @return A bitmask of the properties of the {@code RemoteConnection}, as defined in the
+     *         {@code PROPERTY_*} constants in class {@link Connection}.
+     */
+    public int getConnectionProperties() {
+        return mConnectionProperties;
+    }
+
+    /**
      * Determines if the audio mode of this {@code RemoteConnection} is VOIP.
      *
      * @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
@@ -1114,6 +1137,23 @@
     /**
      * @hide
      */
+    void setConnectionProperties(final int connectionProperties) {
+        mConnectionProperties = connectionProperties;
+        for (CallbackRecord record : mCallbackRecords) {
+            final RemoteConnection connection = this;
+            final Callback callback = record.getCallback();
+            record.getHandler().post(new Runnable() {
+                @Override
+                public void run() {
+                    callback.onConnectionPropertiesChanged(connection, connectionProperties);
+                }
+            });
+        }
+    }
+
+    /**
+     * @hide
+     */
     void setDestroyed() {
         if (!mCallbackRecords.isEmpty()) {
             // Make sure that the callbacks are notified that the call is destroyed first.
@@ -1302,15 +1342,35 @@
     }
 
     /** @hide */
-    void setExtras(final Bundle extras) {
-        mExtras = extras;
+    void putExtras(final Bundle extras) {
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        mExtras.putAll(extras);
+
+        notifyExtrasChanged();
+    }
+
+    /** @hide */
+    void removeExtras(List<String> keys) {
+        if (mExtras == null || keys == null || keys.isEmpty()) {
+            return;
+        }
+        for (String key : keys) {
+            mExtras.remove(key);
+        }
+
+        notifyExtrasChanged();
+    }
+
+    private void notifyExtrasChanged() {
         for (CallbackRecord record : mCallbackRecords) {
             final RemoteConnection connection = this;
             final Callback callback = record.getCallback();
             record.getHandler().post(new Runnable() {
                 @Override
                 public void run() {
-                    callback.onExtrasChanged(connection, extras);
+                    callback.onExtrasChanged(connection, mExtras);
                 }
             });
         }
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index fa7183a..21a7706 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -61,6 +61,7 @@
                 mPendingConnections.remove(connection);
                 // Unconditionally initialize the connection ...
                 connection.setConnectionCapabilities(parcel.getConnectionCapabilities());
+                connection.setConnectionProperties(parcel.getConnectionProperties());
                 if (parcel.getHandle() != null
                     || parcel.getState() != Connection.STATE_DISCONNECTED) {
                     connection.setAddress(parcel.getHandle(), parcel.getHandlePresentation());
@@ -156,6 +157,17 @@
         }
 
         @Override
+        public void setConnectionProperties(String callId, int connectionProperties) {
+            if (mConnectionById.containsKey(callId)) {
+                findConnectionForAction(callId, "setConnectionProperties")
+                        .setConnectionProperties(connectionProperties);
+            } else {
+                findConferenceForAction(callId, "setConnectionProperties")
+                        .setConnectionProperties(connectionProperties);
+            }
+        }
+
+        @Override
         public void setIsConferenced(String callId, String conferenceCallId) {
             // Note: callId should not be null; conferenceCallId may be null
             RemoteConnection connection =
@@ -321,13 +333,20 @@
         }
 
         @Override
-        public void setExtras(String callId, Bundle extras) {
-            if (mConnectionById.containsKey(callId)) {
-                findConnectionForAction(callId, "setExtras")
-                        .setExtras(extras);
+        public void putExtras(String callId, Bundle extras) {
+            if (hasConnection(callId)) {
+                findConnectionForAction(callId, "putExtras").putExtras(extras);
             } else {
-                findConferenceForAction(callId, "setExtras")
-                        .setExtras(extras);
+                findConferenceForAction(callId, "putExtras").putExtras(extras);
+            }
+        }
+
+        @Override
+        public void removeExtras(String callId, List<String> keys) {
+            if (hasConnection(callId)) {
+                findConnectionForAction(callId, "removeExtra").removeExtras(keys);
+            } else {
+                findConferenceForAction(callId, "removeExtra").removeExtras(keys);
             }
         }
 
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index 3ee0e9f..a4c1798 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -79,4 +79,6 @@
     void pullExternalCall(String callId);
 
     void sendCallEvent(String callId, String event, in Bundle extras);
+
+    void onExtrasChanged(String callId, in Bundle extras);
 }
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index dff1b11..9bc8ffe 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -55,6 +55,8 @@
 
     void setConnectionCapabilities(String callId, int connectionCapabilities);
 
+    void setConnectionProperties(String callId, int connectionProperties);
+
     void setIsConferenced(String callId, String conferenceCallId);
 
     void setConferenceMergeFailed(String callId);
@@ -85,7 +87,9 @@
 
     void addExistingConnection(String callId, in ParcelableConnection connection);
 
-    void setExtras(String callId, in Bundle extras);
+    void putExtras(String callId, in Bundle extras);
+
+    void removeExtras(String callId, in List<String> keys);
 
     void onConnectionEvent(String callId, String event, in Bundle extras);
 }
diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
index 0678fe2..49f9b3b 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
@@ -65,4 +65,8 @@
     void pullExternalCall(String callId);
 
     void sendCallEvent(String callId, String event, in Bundle extras);
+
+    void putExtras(String callId, in Bundle extras);
+
+    void removeExtras(String callId, in List<String> keys);
 }
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index ae130d4..bb2b447 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.telephony.IPhoneStateListener;
 import java.util.List;
+import java.lang.ref.WeakReference;
 
 /**
  * A listener class for monitoring changes in specific telephony states
@@ -533,84 +534,101 @@
     /**
      * The callback methods need to be called on the handler thread where
      * this object was created.  If the binder did that for us it'd be nice.
+     *
+     * Using a static class and weak reference here to avoid memory leak caused by the
+     * IPhoneStateListener.Stub callback retaining references to the outside PhoneStateListeners:
+     * even caller has been destroyed and "un-registered" the PhoneStateListener, it is still not
+     * eligible for GC given the references coming from:
+     * Native Stack --> PhoneStateListener --> Context (Activity).
+     * memory of caller's context will be collected after GC from service side get triggered
      */
-    IPhoneStateListener callback = new IPhoneStateListener.Stub() {
+    private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub {
+        private WeakReference<PhoneStateListener> mPhoneStateListenerWeakRef;
+
+        public IPhoneStateListenerStub(PhoneStateListener phoneStateListener) {
+            mPhoneStateListenerWeakRef = new WeakReference<PhoneStateListener>(phoneStateListener);
+        }
+
+        private void send(int what, int arg1, int arg2, Object obj) {
+            PhoneStateListener listener = mPhoneStateListenerWeakRef.get();
+            if (listener != null) {
+                Message.obtain(listener.mHandler, what, arg1, arg2, obj).sendToTarget();
+            }
+        }
+
         public void onServiceStateChanged(ServiceState serviceState) {
-            Message.obtain(mHandler, LISTEN_SERVICE_STATE, 0, 0, serviceState).sendToTarget();
+            send(LISTEN_SERVICE_STATE, 0, 0, serviceState);
         }
 
         public void onSignalStrengthChanged(int asu) {
-            Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTH, asu, 0, null).sendToTarget();
+            send(LISTEN_SIGNAL_STRENGTH, asu, 0, null);
         }
 
         public void onMessageWaitingIndicatorChanged(boolean mwi) {
-            Message.obtain(mHandler, LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null)
-                    .sendToTarget();
+            send(LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null);
         }
 
         public void onCallForwardingIndicatorChanged(boolean cfi) {
-            Message.obtain(mHandler, LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null)
-                    .sendToTarget();
+            send(LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null);
         }
 
         public void onCellLocationChanged(Bundle bundle) {
             CellLocation location = CellLocation.newFromBundle(bundle);
-            Message.obtain(mHandler, LISTEN_CELL_LOCATION, 0, 0, location).sendToTarget();
+            send(LISTEN_CELL_LOCATION, 0, 0, location);
         }
 
         public void onCallStateChanged(int state, String incomingNumber) {
-            Message.obtain(mHandler, LISTEN_CALL_STATE, state, 0, incomingNumber).sendToTarget();
+            send(LISTEN_CALL_STATE, state, 0, incomingNumber);
         }
 
         public void onDataConnectionStateChanged(int state, int networkType) {
-            Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType).
-                    sendToTarget();
+            send(LISTEN_DATA_CONNECTION_STATE, state, networkType, null);
         }
 
         public void onDataActivity(int direction) {
-            Message.obtain(mHandler, LISTEN_DATA_ACTIVITY, direction, 0, null).sendToTarget();
+            send(LISTEN_DATA_ACTIVITY, direction, 0, null);
         }
 
         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-            Message.obtain(mHandler, LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength).sendToTarget();
+            send(LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength);
         }
 
         public void onOtaspChanged(int otaspMode) {
-            Message.obtain(mHandler, LISTEN_OTASP_CHANGED, otaspMode, 0).sendToTarget();
+            send(LISTEN_OTASP_CHANGED, otaspMode, 0, null);
         }
 
         public void onCellInfoChanged(List<CellInfo> cellInfo) {
-            Message.obtain(mHandler, LISTEN_CELL_INFO, 0, 0, cellInfo).sendToTarget();
+            send(LISTEN_CELL_INFO, 0, 0, cellInfo);
         }
 
         public void onPreciseCallStateChanged(PreciseCallState callState) {
-            Message.obtain(mHandler, LISTEN_PRECISE_CALL_STATE, 0, 0, callState).sendToTarget();
+            send(LISTEN_PRECISE_CALL_STATE, 0, 0, callState);
         }
 
         public void onPreciseDataConnectionStateChanged(
                 PreciseDataConnectionState dataConnectionState) {
-            Message.obtain(mHandler, LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0,
-                    dataConnectionState).sendToTarget();
+            send(LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0, dataConnectionState);
         }
 
         public void onDataConnectionRealTimeInfoChanged(
                 DataConnectionRealTimeInfo dcRtInfo) {
-            Message.obtain(mHandler, LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0,
-                    dcRtInfo).sendToTarget();
+            send(LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, dcRtInfo);
         }
 
         public void onVoLteServiceStateChanged(VoLteServiceState lteState) {
-            Message.obtain(mHandler, LISTEN_VOLTE_STATE, 0, 0, lteState).sendToTarget();
+            send(LISTEN_VOLTE_STATE, 0, 0, lteState);
         }
 
         public void onOemHookRawEvent(byte[] rawData) {
-            Message.obtain(mHandler, LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData).sendToTarget();
+            send(LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData);
         }
 
         public void onCarrierNetworkChange(boolean active) {
-            Message.obtain(mHandler, LISTEN_CARRIER_NETWORK_CHANGE, 0, 0, active).sendToTarget();
+            send(LISTEN_CARRIER_NETWORK_CHANGE, 0, 0, active);
         }
-    };
+    }
+
+    IPhoneStateListener callback = new IPhoneStateListenerStub(this);
 
     private void log(String s) {
         Rlog.d(LOG_TAG, s);
diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java
index 96c6243..303746c 100644
--- a/telephony/java/com/android/ims/ImsCallProfile.java
+++ b/telephony/java/com/android/ims/ImsCallProfile.java
@@ -201,7 +201,7 @@
      * "14" vs (int) 14).
      * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
      *      updateWifiStateFromExtras(Bundle)} to determine whether to set the
-     * {@link android.telecom.Connection#CAPABILITY_WIFI} capability on a connection.
+     * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection.
      */
     public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
 
diff --git a/telephony/java/com/android/ims/ImsExternalCallState.java b/telephony/java/com/android/ims/ImsExternalCallState.java
index edb6bfc..71c1837 100644
--- a/telephony/java/com/android/ims/ImsExternalCallState.java
+++ b/telephony/java/com/android/ims/ImsExternalCallState.java
@@ -28,7 +28,7 @@
  */
 
 /**
- * Parcelable object to handle VICE Dialog Information
+ * Parcelable object to handle MultiEndpoint Dialog Information
  * @hide
  */
 public class ImsExternalCallState implements Parcelable {
@@ -39,19 +39,30 @@
     public static final int CALL_STATE_CONFIRMED = 1;
     public static final int CALL_STATE_TERMINATED = 2;
     // Dialog Id
-    public int mCallId;
+    private int mCallId;
     // Number
-    public Uri mAddress;
-    public boolean mIsPullable;
+    private Uri mAddress;
+    private boolean mIsPullable;
     // CALL_STATE_CONFIRMED / CALL_STATE_TERMINATED
-    public int mCallState;
+    private int mCallState;
     // ImsCallProfile#CALL_TYPE_*
-    public int mCallType;
-    public boolean mIsHeld;
+    private int mCallType;
+    private boolean mIsHeld;
 
     public ImsExternalCallState() {
     }
 
+    public ImsExternalCallState(int callId, Uri address, boolean isPullable, int callState,
+            int callType, boolean isCallheld) {
+        mCallId = callId;
+        mAddress = address;
+        mIsPullable = isPullable;
+        mCallState = callState;
+        mCallType = callType;
+        mIsHeld = isCallheld;
+        Rlog.d(TAG, "ImsExternalCallState = " + this);
+    }
+
     public ImsExternalCallState(Parcel in) {
         mCallId = in.readInt();
         ClassLoader classLoader = ImsExternalCallState.class.getClassLoader();
@@ -60,12 +71,7 @@
         mCallState = in.readInt();
         mCallType = in.readInt();
         mIsHeld = (in.readInt() != 0);
-        Rlog.d(TAG, "ImsExternalCallState const = " +
-                "callid = " + getCallId() +
-                ", address = " + getAddress() +
-                ", mCallState = " + getCallState() +
-                ", calltype = " + getCallType() +
-                ", isheld = " + isCallHeld());
+        Rlog.d(TAG, "ImsExternalCallState const = " + this);
     }
 
     @Override
@@ -81,6 +87,7 @@
         out.writeInt(mCallState);
         out.writeInt(mCallType);
         out.writeInt(mIsHeld ? 1 : 0);
+        Rlog.d(TAG, "ImsExternalCallState writeToParcel = " + out.toString());
     }
 
     public static final Parcelable.Creator<ImsExternalCallState> CREATOR =
diff --git a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
index 70a474e..27b8fa1 100644
--- a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl
@@ -32,7 +32,7 @@
      *
      * @return void.
      */
-    void notifyRefreshExternalCallState(in List<ImsExternalCallState> externalCallDialogs);
+    void onImsExternalCallStateUpdate(in List<ImsExternalCallState> externalCallDialogs);
 
 }
 
diff --git a/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl b/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl
index 1bfb9b2..1374caa 100644
--- a/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl
+++ b/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl
@@ -34,5 +34,5 @@
      * Query api to get the latest Dialog Event Package information
      * Should be invoked only after setListener is done
      */
-    void requestDialogEventPackageState();
+    void requestImsExternalCallStateInfo();
 }
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index ea3b5c9..6567ea7 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -218,11 +218,4 @@
      */
     static final String PROPERTY_VIDEOCALL_AUDIO_OUTPUT = "persist.radio.call.audio.output";
 
-    /**
-     * For MultiEndpoint Feature
-     * If true: Dial intent is for call pull functionality
-     * if false: normal dial
-     */
-    static final String EXTRA_IS_CALL_PULL =
-            "android.telephony.extra.IS_CALL_PULL";
 }
diff --git a/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml b/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml
new file mode 100644
index 0000000..5d23d36e
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <domain-config>
+    <domain>android.com
+    </domain>
+    <domain>   developer.android.com    </domain>
+    <pin-set>
+      <pin digest="SHA-256">  7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=  </pin>
+    </pin-set>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
index 4c12c2d..0412bc7 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
@@ -65,4 +65,9 @@
         }
         return certs;
     }
+
+    @Override
+    public void handleTrustStorageUpdate() {
+        // Nothing to do.
+    }
 }
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
index 10bcc18..f7066a6 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
@@ -464,4 +464,16 @@
         } catch (RuntimeException expected) {
         }
     }
+
+    public void testDomainWhitespaceTrimming() throws Exception {
+        XmlConfigSource source =
+                new XmlConfigSource(getContext(), R.xml.domain_whitespace, false);
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        NetworkSecurityConfig defaultConfig = appConfig.getConfigForHostname("");
+        MoreAsserts.assertNotEqual(defaultConfig, appConfig.getConfigForHostname("developer.android.com"));
+        MoreAsserts.assertNotEqual(defaultConfig, appConfig.getConfigForHostname("android.com"));
+        SSLContext context = TestUtils.getSSLContext(source);
+        TestUtils.assertConnectionSucceeds(context, "android.com", 443);
+        TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
+    }
 }
diff --git a/tools/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py
index a848346..75e837b 100755
--- a/tools/fonts/fontchain_lint.py
+++ b/tools/fonts/fontchain_lint.py
@@ -9,17 +9,37 @@
 from fontTools import ttLib
 
 LANG_TO_SCRIPT = {
+    'as': 'Beng',
+    'bn': 'Beng',
+    'cy': 'Latn',
+    'da': 'Latn',
     'de': 'Latn',
     'en': 'Latn',
     'es': 'Latn',
+    'et': 'Latn',
     'eu': 'Latn',
-    'ja': 'Jpan',
-    'ko': 'Kore',
+    'fr': 'Latn',
+    'ga': 'Latn',
+    'gu': 'Gujr',
+    'hi': 'Deva',
+    'hr': 'Latn',
     'hu': 'Latn',
     'hy': 'Armn',
+    'ja': 'Jpan',
+    'kn': 'Knda',
+    'ko': 'Kore',
+    'ml': 'Mlym',
+    'mn': 'Cyrl',
+    'mr': 'Deva',
     'nb': 'Latn',
     'nn': 'Latn',
+    'or': 'Orya',
+    'pa': 'Guru',
     'pt': 'Latn',
+    'sl': 'Latn',
+    'ta': 'Taml',
+    'te': 'Telu',
+    'tk': 'Latn',
 }
 
 def lang_to_script(lang_code):
diff --git a/tools/layoutlib/.idea/codeStyleSettings.xml b/tools/layoutlib/.idea/codeStyleSettings.xml
index 89f7b34..ac90d1e 100644
--- a/tools/layoutlib/.idea/codeStyleSettings.xml
+++ b/tools/layoutlib/.idea/codeStyleSettings.xml
@@ -40,6 +40,7 @@
           <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
         </XML>
         <codeStyleSettings language="JAVA">
+          <option name="KEEP_LINE_BREAKS" value="false" />
           <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
           <option name="CALL_PARAMETERS_WRAP" value="1" />
           <option name="METHOD_PARAMETERS_WRAP" value="1" />
@@ -55,6 +56,7 @@
           <option name="DOWHILE_BRACE_FORCE" value="3" />
           <option name="WHILE_BRACE_FORCE" value="3" />
           <option name="FOR_BRACE_FORCE" value="3" />
+          <option name="WRAP_LONG_LINES" value="true" />
           <arrangement>
             <groups>
               <group>
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
index 985dd5a..ea320c7 100644
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -21,6 +21,7 @@
 import com.android.ide.common.rendering.api.DensityBasedResourceValue;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
+import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
@@ -84,7 +85,7 @@
         return new BridgeTypedArray(resources, resources.mContext, numEntries, platformFile);
     }
 
-    private static Pair<String, ResourceValue> getResourceValue(Resources resources, int id,
+    private static Pair<ResourceType, String> getResourceInfo(Resources resources, int id,
             boolean[] platformResFlag_out) {
         // first get the String related to this id in the framework
         Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
@@ -97,11 +98,7 @@
 
         if (resourceInfo != null) {
             platformResFlag_out[0] = true;
-            String attributeName = resourceInfo.getSecond();
-
-            return Pair.of(attributeName,
-                    resources.mContext.getRenderResources().getFrameworkResource(
-                            resourceInfo.getFirst(), attributeName));
+            return resourceInfo;
         }
 
         // didn't find a match in the framework? look in the project.
@@ -110,13 +107,24 @@
 
             if (resourceInfo != null) {
                 platformResFlag_out[0] = false;
-                String attributeName = resourceInfo.getSecond();
-
-                return Pair.of(attributeName,
-                        resources.mContext.getRenderResources().getProjectResource(
-                                resourceInfo.getFirst(), attributeName));
+                return resourceInfo;
             }
         }
+        return null;
+    }
+
+    private static Pair<String, ResourceValue> getResourceValue(Resources resources, int id,
+            boolean[] platformResFlag_out) {
+        Pair<ResourceType, String> resourceInfo =
+                getResourceInfo(resources, id, platformResFlag_out);
+
+        if (resourceInfo != null) {
+            String attributeName = resourceInfo.getSecond();
+            RenderResources renderResources = resources.mContext.getRenderResources();
+            return Pair.of(attributeName, platformResFlag_out[0] ?
+                    renderResources.getFrameworkResource(resourceInfo.getFirst(), attributeName) :
+                    renderResources.getProjectResource(resourceInfo.getFirst(), attributeName));
+        }
 
         return null;
     }
@@ -626,17 +634,57 @@
 
     @LayoutlibDelegate
     static String getResourceEntryName(Resources resources, int resid) throws NotFoundException {
-        throw new UnsupportedOperationException();
+        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
+        if (resourceInfo != null) {
+            return resourceInfo.getSecond();
+        }
+        throwException(resid, null);
+        return null;
+
     }
 
     @LayoutlibDelegate
     static String getResourceName(Resources resources, int resid) throws NotFoundException {
-        throw new UnsupportedOperationException();
+        boolean[] platformOut = new boolean[1];
+        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
+        String packageName;
+        if (resourceInfo != null) {
+            if (platformOut[0]) {
+                packageName = SdkConstants.ANDROID_NS_NAME;
+            } else {
+                packageName = resources.mContext.getPackageName();
+                packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
+            }
+            return packageName + ':' + resourceInfo.getFirst().getName() + '/' +
+                    resourceInfo.getSecond();
+        }
+        throwException(resid, null);
+        return null;
+    }
+
+    @LayoutlibDelegate
+    static String getResourcePackageName(Resources resources, int resid) throws NotFoundException {
+        boolean[] platformOut = new boolean[1];
+        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
+        if (resourceInfo != null) {
+            if (platformOut[0]) {
+                return SdkConstants.ANDROID_NS_NAME;
+            }
+            String packageName = resources.mContext.getPackageName();
+            return packageName == null ? SdkConstants.APP_PREFIX : packageName;
+        }
+        throwException(resid, null);
+        return null;
     }
 
     @LayoutlibDelegate
     static String getResourceTypeName(Resources resources, int resid) throws NotFoundException {
-        throw new UnsupportedOperationException();
+        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
+        if (resourceInfo != null) {
+            return resourceInfo.getFirst().getName();
+        }
+        throwException(resid, null);
+        return null;
     }
 
     @LayoutlibDelegate
@@ -849,22 +897,17 @@
      * @throws NotFoundException
      */
     private static void throwException(Resources resources, int id) throws NotFoundException {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
+        throwException(id, getResourceInfo(resources, id, new boolean[1]));
+    }
 
-        // if the name is unknown in the framework, get it from the custom view loader.
-        if (resourceInfo == null && resources.mLayoutlibCallback != null) {
-            resourceInfo = resources.mLayoutlibCallback.resolveResourceId(id);
-        }
-
+    private static void throwException(int id, @Nullable Pair<ResourceType, String> resourceInfo) {
         String message;
         if (resourceInfo != null) {
             message = String.format(
                     "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
                     resourceInfo.getFirst(), id, resourceInfo.getSecond());
         } else {
-            message = String.format(
-                    "Could not resolve resource value: 0x%1$X.", id);
+            message = String.format("Could not resolve resource value: 0x%1$X.", id);
         }
 
         throw new NotFoundException(message);
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 7f41348..309c1b8 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -564,7 +564,8 @@
     }
 
     @Override
-    public void requestAppKeyboardShortcuts(IResultReceiver receiver) throws RemoteException {
+    public void requestAppKeyboardShortcuts(
+            IResultReceiver receiver, int deviceId) throws RemoteException {
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
index 411417c..1ea8a9f 100644
--- a/tools/layoutlib/bridge/src/android/view/WindowCallback.java
+++ b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
@@ -141,9 +141,4 @@
     public void onActionModeFinished(ActionMode mode) {
 
     }
-
-    @Override
-    public void onProvideKeyboardShortcuts(List<KeyboardShortcutGroup> data, @Nullable Menu menu) {
-
-    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 533a10a..a83f100 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -103,7 +103,8 @@
     }
 
     @Override
-    public void requestAppKeyboardShortcuts(IResultReceiver receiver) throws RemoteException {
+    public void requestAppKeyboardShortcuts(
+            IResultReceiver receiver, int deviceId) throws RemoteException {
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
index d417eb7..3031701 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
@@ -66,6 +66,6 @@
 
     @Override
     public void requestAppKeyboardShortcuts(
-            KeyboardShortcutsReceiver receiver) {
+            KeyboardShortcutsReceiver receiver, int deviceId) {
     }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index 4e4fcd0..0c53753 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -122,7 +122,7 @@
 
         // build the context
         mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
-                mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(),
+                mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(mParams),
                 mParams.getTargetSdkVersion(), mParams.isRtlSupported());
 
         setUp();
@@ -130,7 +130,6 @@
         return SUCCESS.createResult();
     }
 
-
     /**
      * Prepares the scene for action.
      * <p>
@@ -320,10 +319,11 @@
         }
     }
 
-    private Configuration getConfiguration() {
+    // VisibleForTesting
+    public static Configuration getConfiguration(RenderParams params) {
         Configuration config = new Configuration();
 
-        HardwareConfig hardwareConfig = mParams.getHardwareConfig();
+        HardwareConfig hardwareConfig = params.getHardwareConfig();
 
         ScreenSize screenSize = hardwareConfig.getScreenSize();
         if (screenSize != null) {
@@ -392,7 +392,7 @@
         } else {
             config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_UNDEFINED;
         }
-        String locale = getParams().getLocale();
+        String locale = params.getLocale();
         if (locale != null && !locale.isEmpty()) config.locale = new Locale(locale);
 
         // TODO: fill in more config info.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
index 08a8faf..161bf41 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
@@ -27,8 +27,8 @@
 
 public class DynamicIdMap {
 
-    private final Map<Pair<ResourceType, String>, Integer> mDynamicIds = new HashMap<Pair<ResourceType, String>, Integer>();
-    private final SparseArray<Pair<ResourceType, String>> mRevDynamicIds = new SparseArray<Pair<ResourceType, String>>();
+    private final Map<Pair<ResourceType, String>, Integer> mDynamicIds = new HashMap<>();
+    private final SparseArray<Pair<ResourceType, String>> mRevDynamicIds = new SparseArray<>();
     private int mDynamicSeed;
 
     public DynamicIdMap(int seed) {
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index c2f06e8..a5561fa 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -29,11 +29,14 @@
 import com.android.ide.common.resources.configuration.FolderConfiguration;
 import com.android.io.FolderWrapper;
 import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.impl.RenderAction;
 import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
 import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
 import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
 import com.android.resources.Density;
 import com.android.resources.Navigation;
+import com.android.resources.ResourceType;
 import com.android.utils.ILogger;
 
 import org.junit.AfterClass;
@@ -42,13 +45,15 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.util.DisplayMetrics;
 
 import java.io.File;
-import java.io.FileFilter;
 import java.io.IOException;
 import java.net.URL;
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.concurrent.TimeUnit;
 
 import static org.junit.Assert.assertEquals;
@@ -160,13 +165,8 @@
         if (!host.isDirectory()) {
             return null;
         }
-        File[] hosts = host.listFiles(new FileFilter() {
-            @Override
-            public boolean accept(File path) {
-                return path.isDirectory() && (path.getName().startsWith("linux-") || path.getName()
-                        .startsWith("darwin-"));
-            }
-        });
+        File[] hosts = host.listFiles(path -> path.isDirectory() &&
+                (path.getName().startsWith("linux-") || path.getName().startsWith("darwin-")));
         for (File hostOut : hosts) {
             String platformDir = getPlatformDirFromHostOut(hostOut);
             if (platformDir != null) {
@@ -184,12 +184,9 @@
         if (!sdkDir.isDirectory()) {
             return null;
         }
-        File[] sdkDirs = sdkDir.listFiles(new FileFilter() {
-            @Override
-            public boolean accept(File path) {
-                // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
-                return path.isDirectory() && path.getName().startsWith("sdk");
-            }
+        File[] sdkDirs = sdkDir.listFiles(path -> {
+            // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
+            return path.isDirectory() && path.getName().startsWith("sdk");
         });
         for (File dir : sdkDirs) {
             String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
@@ -201,46 +198,34 @@
     }
 
     private static String getPlatformDirFromHostOutSdkSdk(File sdkDir) {
-        File[] possibleSdks = sdkDir.listFiles(new FileFilter() {
-            @Override
-            public boolean accept(File path) {
-                return path.isDirectory() && path.getName().contains("android-sdk");
-            }
-        });
+        File[] possibleSdks = sdkDir.listFiles(
+                path -> path.isDirectory() && path.getName().contains("android-sdk"));
         for (File possibleSdk : possibleSdks) {
             File platformsDir = new File(possibleSdk, "platforms");
-            File[] platforms = platformsDir.listFiles(new FileFilter() {
-                @Override
-                public boolean accept(File path) {
-                    return path.isDirectory() && path.getName().startsWith("android-");
-                }
-            });
+            File[] platforms = platformsDir.listFiles(
+                    path -> path.isDirectory() && path.getName().startsWith("android-"));
             if (platforms == null || platforms.length == 0) {
                 continue;
             }
-            Arrays.sort(platforms, new Comparator<File>() {
-                // Codenames before ints. Higher APIs precede lower.
-                @Override
-                public int compare(File o1, File o2) {
-                    final int MAX_VALUE = 1000;
-                    String suffix1 = o1.getName().substring("android-".length());
-                    String suffix2 = o2.getName().substring("android-".length());
-                    int suff1, suff2;
-                    try {
-                        suff1 = Integer.parseInt(suffix1);
-                    } catch (NumberFormatException e) {
-                        suff1 = MAX_VALUE;
-                    }
-                    try {
-                        suff2 = Integer.parseInt(suffix2);
-                    } catch (NumberFormatException e) {
-                        suff2 = MAX_VALUE;
-                    }
-                    if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
-                        return suff2 - suff1;
-                    }
-                    return suffix2.compareTo(suffix1);
+            Arrays.sort(platforms, (o1, o2) -> {
+                final int MAX_VALUE = 1000;
+                String suffix1 = o1.getName().substring("android-".length());
+                String suffix2 = o2.getName().substring("android-".length());
+                int suff1, suff2;
+                try {
+                    suff1 = Integer.parseInt(suffix1);
+                } catch (NumberFormatException e) {
+                    suff1 = MAX_VALUE;
                 }
+                try {
+                    suff2 = Integer.parseInt(suffix2);
+                } catch (NumberFormatException e) {
+                    suff2 = MAX_VALUE;
+                }
+                if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
+                    return suff2 - suff1;
+                }
+                return suffix2.compareTo(suffix1);
             });
             return platforms[0].getAbsolutePath();
         }
@@ -261,6 +246,7 @@
             return null;
         }
     }
+
     /**
      * Initialize the bridge and the resource maps.
      */
@@ -325,8 +311,7 @@
     @Test
     public void testExpand() throws ClassNotFoundException {
         // Create the layout pull parser.
-        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
-                "expand_vert_layout.xml");
+        LayoutPullParser parser = createLayoutPullParser("expand_vert_layout.xml");
         // Create LayoutLibCallback.
         LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
         layoutLibCallback.initResources();
@@ -348,8 +333,7 @@
                 .setScreenHeight(300)
                 .setDensity(Density.XHIGH)
                 .setNavigation(Navigation.NONAV);
-        parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
-                "expand_horz_layout.xml");
+        parser = createLayoutPullParser("expand_horz_layout.xml");
         params = getSessionParams(parser, customConfigGenerator,
                 layoutLibCallback, "Theme.Material.Light.NoActionBar.Fullscreen", false,
                 RenderingMode.H_SCROLL, 22);
@@ -361,8 +345,7 @@
     @Test
     public void testVectorAnimation() throws ClassNotFoundException {
         // Create the layout pull parser.
-        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
-                "indeterminate_progressbar.xml");
+        LayoutPullParser parser = createLayoutPullParser("indeterminate_progressbar.xml");
         // Create LayoutLibCallback.
         LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
         layoutLibCallback.initResources();
@@ -373,8 +356,7 @@
 
         renderAndVerify(params, "animated_vector.png", TimeUnit.SECONDS.toNanos(2));
 
-        parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
-                "indeterminate_progressbar.xml");
+        parser = createLayoutPullParser("indeterminate_progressbar.xml");
         params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
                 layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
                 RenderingMode.V_SCROLL, 22);
@@ -388,8 +370,7 @@
     @Test
     public void testVectorDrawable() throws ClassNotFoundException {
         // Create the layout pull parser.
-        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
-                "vector_drawable.xml");
+        LayoutPullParser parser = createLayoutPullParser("vector_drawable.xml");
         // Create LayoutLibCallback.
         LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
         layoutLibCallback.initResources();
@@ -405,8 +386,7 @@
     @Test
     public void testScrolling() throws ClassNotFoundException {
         // Create the layout pull parser.
-        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" +
-                "scrolled.xml");
+        LayoutPullParser parser = createLayoutPullParser("scrolled.xml");
         // Create LayoutLibCallback.
         LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
         layoutLibCallback.initResources();
@@ -435,6 +415,39 @@
         assertEquals(690, rootLayout.getChildren().get(5).getChildren().get(0).getRight());
     }
 
+    @Test
+    public void testGetResourceNameVariants() throws Exception {
+        // Setup
+        SessionParams params = createSessionParams("", ConfigGenerator.NEXUS_4);
+        AssetManager assetManager = AssetManager.getSystem();
+        DisplayMetrics metrics = new DisplayMetrics();
+        Configuration configuration = RenderAction.getConfiguration(params);
+        Resources resources = new Resources(assetManager, metrics, configuration);
+        resources.mLayoutlibCallback = params.getLayoutlibCallback();
+        resources.mContext =
+                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
+                        params.getAssets(), params.getLayoutlibCallback(), configuration,
+                        params.getTargetSdkVersion(), params.isRtlSupported());
+        // Test
+        assertEquals("android:style/ButtonBar",
+                resources.getResourceName(android.R.style.ButtonBar));
+        assertEquals("android", resources.getResourcePackageName(android.R.style.ButtonBar));
+        assertEquals("ButtonBar", resources.getResourceEntryName(android.R.style.ButtonBar));
+        assertEquals("style", resources.getResourceTypeName(android.R.style.ButtonBar));
+        int id = resources.mLayoutlibCallback.getResourceId(ResourceType.STRING, "app_name");
+        assertEquals("com.android.layoutlib.test.myapplication:string/app_name",
+                resources.getResourceName(id));
+        assertEquals("com.android.layoutlib.test.myapplication",
+                resources.getResourcePackageName(id));
+        assertEquals("string", resources.getResourceTypeName(id));
+        assertEquals("app_name", resources.getResourceEntryName(id));
+    }
+
+    @NonNull
+    private LayoutPullParser createLayoutPullParser(String layoutPath) {
+        return new LayoutPullParser(APP_TEST_RES + "/layout/" + layoutPath);
+    }
+
     /**
      * Create a new rendering session and test that rendering the given layout doesn't throw any
      * exceptions and matches the provided image.
@@ -505,16 +518,21 @@
     private RenderResult renderAndVerify(String layoutFileName, String goldenFileName,
             ConfigGenerator deviceConfig)
             throws ClassNotFoundException {
+        SessionParams params = createSessionParams(layoutFileName, deviceConfig);
+        return renderAndVerify(params, goldenFileName);
+    }
+
+    private SessionParams createSessionParams(String layoutFileName, ConfigGenerator deviceConfig)
+            throws ClassNotFoundException {
         // Create the layout pull parser.
-        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" + layoutFileName);
+        LayoutPullParser parser = createLayoutPullParser(layoutFileName);
         // Create LayoutLibCallback.
         LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
         layoutLibCallback.initResources();
         // TODO: Set up action bar handler properly to test menu rendering.
         // Create session params.
-        SessionParams params = getSessionParams(parser, deviceConfig,
+        return getSessionParams(parser, deviceConfig,
                 layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        return renderAndVerify(params, goldenFileName);
     }
 
     /**
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index 6c16ed0..96ae523 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -24,7 +24,9 @@
 import com.android.ide.common.rendering.api.ParserFactory;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.SessionParams.Key;
 import com.android.ide.common.resources.IntArrayWrapper;
+import com.android.layoutlib.bridge.android.RenderParamsFlags;
 import com.android.resources.ResourceType;
 import com.android.util.Pair;
 import com.android.utils.ILogger;
@@ -176,4 +178,12 @@
             }
         };
     }
+
+    @Override
+    public <T> T getFlag(Key<T> key) {
+        if (key.equals(RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE)) {
+            return (T) PACKAGE_NAME;
+        }
+        return null;
+    }
 }
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
index c79b662..1110494 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
@@ -56,9 +56,7 @@
     public LayoutPullParser(File layoutFile) {
         try {
             init(new FileInputStream(layoutFile));
-        } catch (XmlPullParserException e) {
-            throw new IOError(e);
-        } catch (FileNotFoundException e) {
+        } catch (XmlPullParserException | FileNotFoundException e) {
             throw new IOError(e);
         }
     }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index f32bb76..1a00cc9 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -168,6 +168,7 @@
         "android.content.res.Resources#getLayout",
         "android.content.res.Resources#getResourceEntryName",
         "android.content.res.Resources#getResourceName",
+        "android.content.res.Resources#getResourcePackageName",
         "android.content.res.Resources#getResourceTypeName",
         "android.content.res.Resources#getString",
         "android.content.res.Resources#getStringArray",
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index a9259fa..67cf107 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -56,6 +56,11 @@
      */
     public int anqpDomainId;
 
+    /*
+     * This field is equivalent to the |flags|, rather than the |capabilities| field
+     * of the per-BSS scan results returned by WPA supplicant. See the definition of
+     * |struct wpa_bss| in wpa_supplicant/bss.h for more details.
+     */
     /**
      * Describes the authentication, key management, and encryption schemes
      * supported by the access point.
@@ -211,6 +216,10 @@
     /** {@hide} */
     public static final long FLAG_80211mc_RESPONDER               = 0x0000000000000002;
 
+    /*
+     * These flags are specific to the ScanResult class, and are not related to the |flags|
+     * field of the per-BSS scan results from WPA supplicant.
+     */
     /**
      * Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}.
      * {@hide}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 7dc8049..06dea07 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -684,6 +684,13 @@
 
     /**
      * @hide
+     * A hint about whether or not the network represented by this WifiConfiguration
+     * is metered.
+     */
+    public boolean meteredHint;
+
+    /**
+     * @hide
      * Number of time the scorer overrode a the priority based choice, when comparing two
      * WifiConfigurations, note that since comparing WifiConfiguration happens very often
      * potentially at every scan, this number might become very large, even on an idle
@@ -1302,6 +1309,7 @@
         selfAdded = false;
         didSelfAdd = false;
         ephemeral = false;
+        meteredHint = false;
         validatedInternetAccess = false;
         mIpConfiguration = new IpConfiguration();
         lastUpdateUid = -1;
@@ -1399,7 +1407,9 @@
         if (this.selfAdded) sbuf.append(" selfAdded");
         if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess");
         if (this.ephemeral) sbuf.append(" ephemeral");
-        if (this.didSelfAdd || this.selfAdded || this.validatedInternetAccess || this.ephemeral) {
+        if (this.meteredHint) sbuf.append(" meteredHint");
+        if (this.didSelfAdd || this.selfAdded || this.validatedInternetAccess
+            || this.ephemeral || this.meteredHint) {
             sbuf.append("\n");
         }
         sbuf.append(" KeyMgmt:");
@@ -1546,18 +1556,6 @@
         return sbuf.toString();
     }
 
-    /**
-     * Construct a WifiConfiguration from a scanned network
-     * @param scannedAP the scan result used to construct the config entry
-     * TODO: figure out whether this is a useful way to construct a new entry.
-     *
-    public WifiConfiguration(ScanResult scannedAP) {
-        networkId = -1;
-        SSID = scannedAP.SSID;
-        BSSID = scannedAP.BSSID;
-    }
-    */
-
     /** {@hide} */
     public String getPrintableSsid() {
         if (SSID == null) return "";
@@ -1832,6 +1830,7 @@
             selfAdded = source.selfAdded;
             validatedInternetAccess = source.validatedInternetAccess;
             ephemeral = source.ephemeral;
+            meteredHint = source.meteredHint;
             if (source.visibility != null) {
                 visibility = new Visibility(source.visibility);
             }
@@ -1870,11 +1869,6 @@
         }
     }
 
-    /** {@hide} */
-    //public static final int NOTHING_TAG = 0;
-    /** {@hide} */
-    //public static final int SCAN_CACHE_TAG = 1;
-
     /** Implement the Parcelable interface {@hide} */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
@@ -1916,6 +1910,7 @@
         dest.writeInt(didSelfAdd ? 1 : 0);
         dest.writeInt(validatedInternetAccess ? 1 : 0);
         dest.writeInt(ephemeral ? 1 : 0);
+        dest.writeInt(meteredHint ? 1 : 0);
         dest.writeInt(creatorUid);
         dest.writeInt(lastConnectUid);
         dest.writeInt(lastUpdateUid);
@@ -1985,6 +1980,7 @@
                 config.didSelfAdd = in.readInt() != 0;
                 config.validatedInternetAccess = in.readInt() != 0;
                 config.ephemeral = in.readInt() != 0;
+                config.meteredHint = in.readInt() != 0;
                 config.creatorUid = in.readInt();
                 config.lastConnectUid = in.readInt();
                 config.lastUpdateUid = in.readInt();
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index c5e7bff..ecf54474f 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -277,6 +277,12 @@
          * non-zero => scan was truncated, so results may not be complete
          */
         private int mFlags;
+        /**
+         * Indicates the buckets that were scanned to generate these results.
+         * This is not relevant to WifiScanner API users and is used internally.
+         * {@hide}
+         */
+        private int mBucketsScanned;
         /** all scan results discovered in this scan, sorted by timestamp in ascending order */
         private ScanResult mResults[];
 
@@ -288,9 +294,18 @@
             mResults = results;
         }
 
+        /** {@hide} */
+        public ScanData(int id, int flags, int bucketsScanned, ScanResult[] results) {
+            mId = id;
+            mFlags = flags;
+            mBucketsScanned = bucketsScanned;
+            mResults = results;
+        }
+
         public ScanData(ScanData s) {
             mId = s.mId;
             mFlags = s.mFlags;
+            mBucketsScanned = s.mBucketsScanned;
             mResults = new ScanResult[s.mResults.length];
             for (int i = 0; i < s.mResults.length; i++) {
                 ScanResult result = s.mResults[i];
@@ -321,6 +336,7 @@
             if (mResults != null) {
                 dest.writeInt(mId);
                 dest.writeInt(mFlags);
+                dest.writeInt(mBucketsScanned);
                 dest.writeInt(mResults.length);
                 for (int i = 0; i < mResults.length; i++) {
                     ScanResult result = mResults[i];
@@ -337,12 +353,13 @@
                     public ScanData createFromParcel(Parcel in) {
                         int id = in.readInt();
                         int flags = in.readInt();
+                        int bucketsScanned = in.readInt();
                         int n = in.readInt();
                         ScanResult results[] = new ScanResult[n];
                         for (int i = 0; i < n; i++) {
                             results[i] = ScanResult.CREATOR.createFromParcel(in);
                         }
-                        return new ScanData(id, flags, results);
+                        return new ScanData(id, flags, bucketsScanned, results);
                     }
 
                     public ScanData[] newArray(int size) {