Merge "Compute text bounds on a per glyph basis when drawing from an SkPicture." 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 0177e4f..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;
   }
@@ -29566,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);
@@ -29895,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);
@@ -34582,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, int);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -36228,9 +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 static java.lang.String propertiesToString(int);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -36256,8 +36260,8 @@
     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_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     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
@@ -57401,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[]);
@@ -66415,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 7956826..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;
   }
@@ -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);
@@ -37030,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, int);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -38802,9 +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 static java.lang.String propertiesToString(int);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -38830,8 +38835,8 @@
     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_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     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
@@ -60464,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[]);
@@ -69478,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 264b5eb..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;
   }
@@ -29632,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);
@@ -29961,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);
@@ -34341,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);
   }
@@ -34653,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, int);
     method public boolean onSearchRequested(android.view.SearchEvent);
     method public boolean onSearchRequested();
     method public void onWakeUp();
@@ -36299,9 +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 static java.lang.String propertiesToString(int);
     method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
     method public final void setActive();
     method public final void setAddress(android.net.Uri, int);
@@ -36327,8 +36332,8 @@
     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_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000
     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
@@ -57474,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[]);
@@ -66488,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/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/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/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/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/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/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 84605bb..ea251f6 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3648,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,
@@ -3735,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 e8a3438..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,6 +215,7 @@
         serialNumber = orig.serialNumber;
         creationTime = orig.creationTime;
         lastLoggedInTime = orig.lastLoggedInTime;
+        lastLoggedInFingerprint = orig.lastLoggedInFingerprint;
         partial = orig.partial;
         profileGroupId = orig.profileGroupId;
         restrictedProfileParentId = orig.restrictedProfileParentId;
@@ -241,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);
@@ -265,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/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/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/core/java/android/os/IProgressListener.aidl b/core/java/android/os/IProgressListener.aidl
new file mode 100644
index 0000000..ad58a7c
--- /dev/null
+++ b/core/java/android/os/IProgressListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.os;
+
+import android.os.Bundle;
+
+/** @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 34c0b14..c028e15 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -65,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>
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/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/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/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7c06577..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) {
@@ -5865,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,
@@ -7090,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/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/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 cf5cc3e..4bb0c3c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -317,7 +317,6 @@
     /**
      * The InputConnection that was last retrieved from the served view.
      */
-    InputConnection mServedInputConnection;
     ControlledInputConnectionWrapper mServedInputConnectionWrapper;
     /**
      * The completions that were last provided by the served view.
@@ -498,7 +497,7 @@
                             // from a thread that created mServedView. That could happen
                             // the current activity is running in the system process.
                             // In that case, we really should not call
-                            // mServedInputConnection.finishComposingText.
+                            // mServedInputConnectionWrapper.finishComposingText().
                             if (checkFocusNoStartInput(mHasBeenInactive, false)) {
                                 final int reason = active ?
                                         InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS :
@@ -532,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
@@ -562,7 +564,9 @@
 
         @Override
         public String toString() {
-            return "ControlledInputConnectionWrapper{mActive=" + mActive
+            return "ControlledInputConnectionWrapper{"
+                    + "connection=" + getInputConnection()
+                    + " finished=" + isFinished()
                     + " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
                     + "}";
         }
@@ -780,7 +784,8 @@
      */
     public boolean isAcceptingText() {
         checkFocus();
-        return mServedInputConnection != null;
+        return mServedInputConnectionWrapper != null &&
+                mServedInputConnectionWrapper.getInputConnection() != null;
     }
 
     /**
@@ -815,7 +820,6 @@
      */
     void clearConnectionLocked() {
         mCurrentTextBoxAttribute = null;
-        mServedInputConnection = null;
         if (mServedInputConnectionWrapper != null) {
             mServedInputConnectionWrapper.deactivate();
             mServedInputConnectionWrapper = null;
@@ -836,7 +840,6 @@
                     throw e.rethrowFromSystemServer();
                 }
             }
-            notifyInputConnectionFinished();
             mServedView = null;
             mCompletions = null;
             mServedConnecting = false;
@@ -844,37 +847,6 @@
         }
     }
 
-    /**
-     * Notifies the served view that the current InputConnection will no longer be used.
-     */
-    private void notifyInputConnectionFinished() {
-        if (mServedView != null && mServedInputConnection != null) {
-            // 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(mServedInputConnection);
-            }
-        }
-    }
-
-    /**
-     * Called from the FINISH_INPUT_CONNECTION message above.
-     * @hide
-     */
-    public void reportFinishInputConnection(InputConnection ic) {
-        if (mServedInputConnection != 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) {
@@ -1240,9 +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();
-            mServedInputConnection = ic;
+            if (mServedInputConnectionWrapper != null) {
+                mServedInputConnectionWrapper.deactivate();
+                mServedInputConnectionWrapper = null;
+            }
             ControlledInputConnectionWrapper servedContext;
             final int missingMethodFlags;
             if (ic != null) {
@@ -1267,9 +1240,6 @@
                 servedContext = null;
                 missingMethodFlags = 0;
             }
-            if (mServedInputConnectionWrapper != null) {
-                mServedInputConnectionWrapper.deactivate();
-            }
             mServedInputConnectionWrapper = servedContext;
 
             try {
@@ -1413,7 +1383,7 @@
             return false;
         }
 
-        InputConnection ic = null;
+        final ControlledInputConnectionWrapper ic;
         synchronized (mH) {
             if (mServedView == mNextServedView && !forceNewFocus) {
                 return false;
@@ -1433,7 +1403,7 @@
                 return false;
             }
 
-            ic = mServedInputConnection;
+            ic = mServedInputConnectionWrapper;
 
             mServedView = mNextServedView;
             mCurrentTextBoxAttribute = null;
@@ -2282,7 +2252,7 @@
         } else {
             p.println("  mCurrentTextBoxAttribute: null");
         }
-        p.println("  mServedInputConnection=" + mServedInputConnection);
+        p.println("  mServedInputConnectionWrapper=" + mServedInputConnectionWrapper);
         p.println("  mCompletions=" + Arrays.toString(mCompletions));
         p.println("  mCursorRect=" + mCursorRect);
         p.println("  mCursorSelStart=" + mCursorSelStart
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/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/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 bdf2a21..9904893 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) {
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 b243cac..9e5c238 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -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/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/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index 3be15f3..6c1ebb4 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -16,6 +16,10 @@
 
 package com.android.internal.view;
 
+import com.android.internal.annotations.GuardedBy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -23,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;
@@ -56,11 +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;
 
-    private 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;
@@ -80,12 +91,25 @@
         }
     }
     
-    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() {
+        synchronized (mLock) {
+            return mInputConnection;
+        }
+    }
+
+    protected boolean isFinished() {
+        synchronized (mLock) {
+            return mFinished;
+        }
+    }
+
     abstract protected boolean isActive();
 
     /**
@@ -198,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
@@ -210,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);
@@ -232,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);
@@ -248,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);
@@ -264,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);
@@ -280,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);
@@ -294,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;
@@ -304,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;
@@ -313,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;
@@ -322,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;
@@ -331,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;
@@ -340,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;
@@ -349,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;
@@ -359,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;
@@ -368,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
@@ -381,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;
@@ -391,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;
@@ -400,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;
@@ -409,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;
@@ -418,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;
@@ -427,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;
@@ -436,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;
@@ -447,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;
@@ -460,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);
@@ -473,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/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/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..91624e7 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..3e463f1 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..6cb94c3 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-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 23d72dc..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/dimens.xml b/core/res/res/values/dimens.xml
index 9b7b1d4..71d9a1f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -452,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 7426ddf..6526571 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1512,6 +1512,9 @@
   <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" />
@@ -1860,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/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/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/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/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/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index e1c9319..059e9ae 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -42,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;
 }
 
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 73027e2..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,
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 99400c6..dca56d4 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -387,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) {
@@ -429,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 42dabd3..1c240db 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -226,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) {
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/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index aa99248..d0ef37c 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -358,9 +358,10 @@
     /**
      * Returns object size in 64-bit integer.
      *
-     * The object size stored in MtpObjectInfo is unsigned 32-bit integer.
-     * The methods reads 64-bit object size from the object property so that it can fetch 4GB+
-     * object size correctly.
+     * 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 {
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index f7c6770..6e434b2 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -701,6 +701,8 @@
     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);
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..c4a77aa 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 outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> aos teus datos, incluídas as fotos e os vídeos da <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</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 7a35bc2..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-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..ea5af3d 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -111,6 +111,8 @@
     <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>
+    <!-- no translation found for open_external_dialog_root_request (8899108702926347720) -->
+    <skip />
     <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/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 2af6c46..bed8b29 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -381,7 +381,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/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 062f2d1..4acf85e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -1049,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/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/src/com/android/mtp/AppFuse.java b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
index 1fd471c..777dc60 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
@@ -144,6 +144,8 @@
             return mCallback.getFileSize(inode);
         } catch (FileNotFoundException e) {
             return -OsConstants.ENOENT;
+        } catch (UnsupportedOperationException e) {
+            return -OsConstants.ENOTSUP;
         }
     }
 
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 4152d1e..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,11 +234,14 @@
             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(
@@ -389,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;
@@ -544,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();
@@ -595,12 +600,20 @@
                 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
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/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 46a570d..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 2608ed4..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..5a73659 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..e523d48 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,7 @@
     <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>
+    <!-- no translation found for print_cannot_load_page (6179560924492912009) -->
+    <skip />
     <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/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/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/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/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/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/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4f3db05..b9aa26b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -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/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 88230bc..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>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6f0f30d..a523a41 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1530,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/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/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/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 1261a9a..fe7ac71 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -34,6 +34,7 @@
 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;
@@ -43,6 +44,7 @@
 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;
@@ -71,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;
@@ -281,6 +284,11 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         registerReceiver(mSystemBroadcastReceiver, filter);
+
+        getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION);
+
+        // Reload the stack view
+        reloadStackView();
     }
 
     @Override
@@ -293,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();
@@ -324,38 +334,21 @@
         loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
         loader.loadTasks(this, loadPlan, loadOpts);
         TaskStack stack = loadPlan.getTaskStack();
-        mRecentsView.onResume(mIsVisible, false /* multiWindowChange */, 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);
@@ -365,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);
@@ -373,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
@@ -380,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();
 
@@ -391,7 +412,34 @@
     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
@@ -450,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, true /* multiWindowChange */, loadPlan.getTaskStack());
-
-        EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
-    }
-
-    @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_TAB: {
@@ -602,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;
@@ -688,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 ab3b79e..77f7739 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -31,8 +31,6 @@
     public boolean launchedFromApp;
     public boolean launchedFromAppDocked;
     public boolean launchedFromHome;
-    public boolean launchedReuseTaskStackViews;
-    public boolean launchedHasConfigurationChanged;
     public boolean launchedViaDragGesture;
     public boolean launchedWhileDocking;
     public int launchedToTaskId;
@@ -45,7 +43,6 @@
         launchedFromAppDocked = false;
         launchedToTaskId = -1;
         launchedWithAltTab = false;
-        launchedHasConfigurationChanged = false;
         launchedViaDragGesture = false;
         launchedWhileDocking = false;
     }
@@ -53,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/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 2afb09a..40613f0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -47,11 +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
-    public boolean hasTransposedNavBar;
-
     // 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.
@@ -79,13 +74,6 @@
     }
 
     /**
-     * Updates the configuration based on the current state of the system
-     */
-    void update(Rect systemInsets) {
-        hasTransposedNavBar = systemInsets.right > 0;
-    }
-
-    /**
      * Returns the activity launch state.
      * TODO: This will be refactored out of RecentsConfiguration.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 3ff33a8..7daef64 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -43,8 +43,10 @@
 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;
@@ -124,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;
@@ -131,7 +140,6 @@
     protected Context mContext;
     protected Handler mHandler;
     TaskStackListenerImpl mTaskStackListener;
-    protected boolean mCanReuseTaskStackViews = true;
     boolean mDraggingInRecents;
     boolean mLaunchedWhileDocking;
 
@@ -200,8 +208,6 @@
     public void onConfigurationChanged() {
         reloadHeaderBarLayout();
         updateHeaderBarLayout(null /* stack */);
-        // Don't reuse task stack views if the configuration changes
-        mCanReuseTaskStackViews = false;
         Recents.getConfiguration().updateOnConfigurationChange();
     }
 
@@ -583,9 +589,6 @@
         calculateWindowStableInsets(systemInsets, windowRect);
         windowRect.offsetTo(0, 0);
 
-        // Update the configuration for the current state
-        Recents.getConfiguration().update(systemInsets);
-
         TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
         stackLayout.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right,
                 mTaskStackBounds);
@@ -596,8 +599,7 @@
         if (stack != null) {
             stackLayout.initialize(windowRect, taskStackBounds,
                     TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
-            mDummyStackView.setTasks(stack, false /* notifyStackChanges */,
-                    false /* relayoutTaskStack */, false /* multiWindowChange */);
+            mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
         }
         Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
         if (!taskViewBounds.equals(mLastTaskViewBounds)) {
@@ -706,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);
@@ -773,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;
@@ -853,10 +855,8 @@
         launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
         launchState.launchedFromAppDocked = mLaunchedWhileDocking;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
-        launchState.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
         launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks;
         launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails;
-        launchState.launchedHasConfigurationChanged = false;
         launchState.launchedViaDragGesture = mDraggingInRecents;
         launchState.launchedWhileDocking = mLaunchedWhileDocking;
 
@@ -906,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/AppTransitionFinishedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java
new file mode 100644
index 0000000..4738eed
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/AppTransitionFinishedEvent.java
@@ -0,0 +1,25 @@
+/*
+ * 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.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Sent when an app transition has finished playing.
+ */
+public class AppTransitionFinishedEvent extends EventBus.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/DockedFirstAnimationFrameEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java
new file mode 100644
index 0000000..32d9a70
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedFirstAnimationFrameEvent.java
@@ -0,0 +1,25 @@
+/*
+ * 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.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus.Event;
+
+/**
+ * Sent when the window animation has started when docking a task
+ */
+public class DockedFirstAnimationFrameEvent extends Event {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
new file mode 100644
index 0000000..cdcabf0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ForcedResizableEvent.java
@@ -0,0 +1,34 @@
+/*
+ * 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.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Sent when recents received the information that an activity got forced resizable, and we need
+ * to inform the user about that.
+ */
+public class ForcedResizableEvent extends EventBus.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/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index ea4888d..3b759c02 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -52,6 +52,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
@@ -64,9 +65,8 @@
 import android.util.Log;
 import android.util.MutableBoolean;
 import android.view.Display;
+import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IDockedStackListener;
-import android.view.Surface;
-import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowManager.KeyboardShortcutsReceiver;
 import android.view.WindowManagerGlobal;
@@ -141,6 +141,7 @@
         public void onActivityPinned() { }
         public void onPinnedActivityRestartAttempt() { }
         public void onPinnedStackAnimationEnded() { }
+        public void onActivityForcedResizable(String packageName, int taskId) { }
     }
 
     /**
@@ -172,10 +173,17 @@
             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}.
+     * List of {@link TaskStackListener} registered from {@link #registerTaskStackListener}.
      */
     private List<TaskStackListener> mTaskStackListeners = new ArrayList<>();
 
@@ -393,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());
@@ -1045,11 +1052,34 @@
         }
     }
 
+    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) {
@@ -1078,6 +1108,13 @@
                     }
                     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/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index dbb692c..82c81ae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -274,7 +274,9 @@
             new TaskKeyLruCache.EvictionCallback() {
         @Override
         public void onEntryEvicted(Task.TaskKey key) {
-            mActivityInfoCache.remove(key.getComponent());
+            if (key != null) {
+                mActivityInfoCache.remove(key.getComponent());
+            }
         }
     };
 
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 a930791..5a2507d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -220,6 +220,11 @@
          */
         void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
             Task newFrontMostTask, AnimationProps animation, boolean fromDockGesture);
+
+        /**
+         * Notifies when tasks in the stack have been updated.
+         */
+        void onStackTasksUpdated(TaskStack stack);
     }
 
     /**
@@ -560,14 +565,19 @@
         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);
+        }
     }
 
     /**
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 2c34523..134b90c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -105,7 +105,11 @@
         }
 
         @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() { }
@@ -309,7 +313,7 @@
         RecentsActivityLaunchState launchState = config.getLaunchState();
         boolean wasLaunchedByAm = !launchState.launchedFromHome &&
                 !launchState.launchedFromApp;
-        if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
+        if (wasLaunchedByAm) {
             EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
         }
 
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 aa27325..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;
@@ -101,8 +104,6 @@
         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);
@@ -115,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/TaskStackHorizontalGridView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
index 22ade9f..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
@@ -156,4 +156,9 @@
             }
         }
     }
+
+    @Override
+    public void onStackTasksUpdated(TaskStack stack) {
+        // Do nothing
+    }
 }
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 29da476..98616f4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -24,6 +24,7 @@
 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;
@@ -32,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;
@@ -52,6 +51,7 @@
 import com.android.systemui.recents.model.TaskStack;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -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 70c4c81..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;
@@ -52,6 +53,7 @@
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.events.EventBus;
 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.HideStackActionButtonEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskEvent;
@@ -68,6 +70,7 @@
 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;
 
@@ -84,8 +87,6 @@
     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 TextView mStackActionButton;
@@ -123,18 +124,17 @@
         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.EnableStackActionButton) {
-            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button, this,
-                    false);
+            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) {
@@ -156,19 +156,17 @@
         setBackground(mBackgroundScrim);
     }
 
-    /** Set/get the bsp root node */
-    public void onResume(boolean isResumingFromVisible, boolean multiWindowChange,
-            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 (!multiWindowChange &&
-                (mTaskStackView == null || !launchState.launchedReuseTaskStackViews)) {
+        if (mTaskStackView == null) {
             isResumingFromVisible = false;
-            removeView(mTaskStackView);
             mTaskStackView = new TaskStackView(getContext());
             mTaskStackView.setSystemInsets(mSystemInsets);
-            mStack = mTaskStackView.getStack();
             addView(mTaskStackView);
         }
 
@@ -177,9 +175,7 @@
         mLastTaskLaunchedWasFreeform = false;
 
         // Update the stack
-        mTaskStackView.onResume(isResumingFromVisible);
-        mTaskStackView.setTasks(stack, isResumingFromVisible /* notifyStackChanges */,
-                true /* relayoutTaskStack */, multiWindowChange);
+        mTaskStackView.onReload(isResumingFromVisible);
 
         if (isResumingFromVisible) {
             // If we are already visible, then restore the background scrim
@@ -189,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) {
@@ -205,6 +209,13 @@
     }
 
     /**
+     * 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() {
@@ -484,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 {
@@ -518,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());
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 6bdaaf9..9c8189a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -46,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 4155dd2..1c7d609 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -152,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();
@@ -354,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) {
@@ -386,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
@@ -395,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();
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 83f8b7e..8a1727a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -852,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;
@@ -953,14 +953,8 @@
      */
     public void getTaskStackBounds(Rect windowRect, int topInset, int rightInset,
             Rect taskStackBounds) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        if (config.hasTransposedNavBar) {
-            taskStackBounds.set(windowRect.left, windowRect.top + topInset,
-                    windowRect.right - rightInset, windowRect.bottom);
-        } else {
-            taskStackBounds.set(windowRect.left, windowRect.top + topInset,
-                    windowRect.right - rightInset, windowRect.bottom);
-        }
+        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();
@@ -1105,9 +1099,11 @@
     private int getScaleForExtent(Rect instance, Rect other, int value, int minValue,
                                   @Extent int extent) {
         if (extent == WIDTH) {
-            return Math.max(minValue, (int) (((float) instance.width() / other.width()) * value));
+            float scale = Utilities.clamp01((float) instance.width() / other.width());
+            return Math.max(minValue, (int) (scale * value));
         } else if (extent == HEIGHT) {
-            return Math.max(minValue, (int) (((float) instance.height() / other.height()) * value));
+            float scale = Utilities.clamp01((float) instance.height() / other.height());
+            return Math.max(minValue, (int) (scale * value));
         }
         return value;
     }
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 c9cc1e9..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;
@@ -87,6 +88,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;
 
@@ -109,17 +112,30 @@
 
     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 = 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_")
@@ -148,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;
@@ -223,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);
@@ -255,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);
@@ -304,34 +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,
-            boolean multiWindowChange) {
+    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);
-            if (!multiWindowChange) {
-                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. */
@@ -342,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());
     }
 
@@ -771,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;
@@ -1177,6 +1182,7 @@
      */
     public void setSystemInsets(Rect systemInsets) {
         if (!systemInsets.equals(mLayoutAlgorithm.mSystemInsets)) {
+            mStableLayoutAlgorithm.setSystemInsets(systemInsets);
             mLayoutAlgorithm.setSystemInsets(systemInsets);
             requestLayout();
         }
@@ -1205,17 +1211,17 @@
         }
 
         // Compute the rects in the stack algorithm
+        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
@@ -1244,12 +1250,11 @@
         } 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));
     }
 
@@ -1288,7 +1293,7 @@
         } 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);
@@ -1439,6 +1444,22 @@
         }
     }
 
+    @Override
+    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 ****/
 
     @Override
@@ -1911,9 +1932,25 @@
     }
 
     public final void onBusEvent(ConfigurationChangedEvent event) {
+        mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
         mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
-        mLayoutAlgorithm.initialize(mWindowRect, 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();
     }
 
     /**
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 0c47b13..c085d80 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -24,6 +24,7 @@
 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.Outline;
 import android.graphics.Paint;
@@ -191,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 */
@@ -237,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);
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 62995a6..ddea4d9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -250,6 +250,44 @@
         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();
@@ -269,37 +307,9 @@
                 R.dimen.recents_task_view_header_button_padding_tablet_land);
         updateLayoutParams(mIconView, findViewById(R.id.title_container), mMoveTaskButton,
                 mDismissButton);
-    }
-
-    /**
-     * 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.leftMargin = mHeaderBarHeight;
-        lp.rightMargin = mMoveTaskButton != null
-                ? 2 * mHeaderBarHeight
-                : mHeaderBarHeight;
-        title.setLayoutParams(lp);
-        if (secondaryButton != null) {
-            lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
-            lp.rightMargin = mHeaderBarHeight;
-            secondaryButton.setLayoutParams(lp);
-            secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
-                    mHeaderButtonPadding, mHeaderButtonPadding);
+        if (mAppOverlayView != null) {
+            updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
         }
-        lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
-        button.setLayoutParams(lp);
-        button.setPadding(mHeaderButtonPadding, mHeaderButtonPadding, mHeaderButtonPadding,
-                mHeaderButtonPadding);
     }
 
     @Override
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 e9c09ac..3eeabc7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -243,11 +243,6 @@
     public void updateThumbnailScale() {
         mThumbnailScale = 1f;
         if (mBitmapShader != null) {
-
-            if (mThumbnailInfo != null) {
-                System.out.println(mTask.title + " bounds: " + mThumbnailInfo.taskWidth + "x" + mThumbnailInfo.taskHeight + ", " + mThumbnailInfo.screenOrientation);
-            }
-
             // 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;
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/stackdivider/events/StartedDragingEvent.java b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java
new file mode 100644
index 0000000..5d19851
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StartedDragingEvent.java
@@ -0,0 +1,25 @@
+/*
+ * 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.events;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Sent when the divider is being draged either manually or by an animation.
+ */
+public class StartedDragingEvent extends EventBus.Event {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java
new file mode 100644
index 0000000..c50d6d6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/events/StoppedDragingEvent.java
@@ -0,0 +1,25 @@
+/*
+ * 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.events;
+
+import com.android.systemui.recents.events.EventBus;
+
+/**
+ * Sent when the divider isn't draging anymore.
+ */
+public class StoppedDragingEvent extends EventBus.Event {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 0ffab5b..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(int deviceId);
-        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);
@@ -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);
@@ -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/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 726aed3..4add3cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -24,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;
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 d9a0f43..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;
@@ -1208,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);
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 9b1f338..bb77c5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -120,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;
@@ -283,7 +284,7 @@
     HotspotControllerImpl mHotspotController;
     RotationLockControllerImpl mRotationLockController;
     UserInfoController mUserInfoController;
-    ZenModeController mZenModeController;
+    protected ZenModeController mZenModeController;
     CastControllerImpl mCastController;
     VolumeComponent mVolumeComponent;
     KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -4310,6 +4311,7 @@
     @Override
     public void appTransitionCancelled() {
         mIconController.appTransitionCancelled();
+        EventBus.getDefault().send(new AppTransitionFinishedEvent());
     }
 
     @Override
@@ -4326,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/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/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/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/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/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 c1a352c..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 {
@@ -583,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");
@@ -603,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));
                 }
             }
 
@@ -723,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) {
@@ -1683,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();
@@ -1713,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);
@@ -2206,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);
@@ -2252,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/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1abb5ff..8b67d0e 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;
 
@@ -1113,8 +1105,6 @@
     boolean mBooting = false;
     boolean mCallFinishBooting = false;
     boolean mBootAnimationComplete = false;
-    boolean mWaitingUpdate = false;
-    boolean mDidUpdate = false;
     boolean mOnBattery = false;
     boolean mLaunchWarningShown = false;
 
@@ -1471,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;
@@ -2019,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;
@@ -4479,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,
@@ -6262,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);
 
@@ -10385,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
@@ -10976,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++) {
@@ -11426,10 +11384,12 @@
                     // Get the focused task before launching launcher.
 
                     if (mUserController.isLockScreenDisabled(currentUserId)) {
+
                         // 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) {
-                            startActivityFromRecentsInner(mFocusedActivity.task.taskId, null);
+                            mStackSupervisor.startActivityFromRecentsInner(
+                                    mFocusedActivity.task.taskId, null);
                         }
                     } else {
                         // Showing launcher to avoid user entering credential twice.
@@ -12606,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) {
@@ -12803,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;
         }
@@ -20757,8 +20510,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
@@ -21033,6 +20786,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 {
@@ -21121,7 +20888,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 5cb04c8..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) {
@@ -4875,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..0e6d174 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;
     }
 
@@ -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/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/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..d7a1920 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;
             }
         }
     }
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/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/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 49ae293..9b92e4f 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2803,7 +2803,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/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/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 5ceb65f..4ca615d 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -138,9 +138,8 @@
         boolean isProfileGuidedFilter = DexFile.isProfileGuidedCompilerFilter(targetCompilerFilter);
         // If any part of the app is used by other apps, we cannot use profile-guided
         // compilation.
-        // TODO: This needs to be refactored to be also checked when the target mode is
-        //       profile-guided.
-        if (isProfileGuidedFilter) {
+        // 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;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 64f8c98..a937738 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -444,13 +444,14 @@
     }
 
     // Compilation reasons.
-    public static final int REASON_BOOT = 0;
-    public static final int REASON_INSTALL = 1;
-    public static final int REASON_BACKGROUND_DEXOPT = 2;
-    public static final int REASON_AB_OTA = 3;
-    public static final int REASON_NON_SYSTEM_LIBRARY = 4;
-    public static final int REASON_SHARED_APK = 5;
-    public static final int REASON_FORCED_DEXOPT = 6;
+    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;
 
@@ -473,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;
@@ -2206,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;
@@ -2222,6 +2225,10 @@
                 }
             }
 
+            // When upgrading form pre-N, we need to handle package extraction like first boot,
+            // as there is no profiling data available.
+            mIsPreNUpgrade = ver.sdkVersion <= Build.VERSION_CODES.M;
+
             // Collect vendor overlay packages.
             // (Do this before scanning any apps.)
             // For security and version matching reason, only consider
@@ -6910,10 +6917,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;
         }
 
@@ -6945,7 +6960,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 /* checkProfiles */, REASON_BOOT, prunedCache);
+                         false /* checkProfiles */,
+                         causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
+                         causePrunedCache);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 238e410..f1b7991 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -26,7 +26,8 @@
 class PackageManagerServiceCompilerMapping {
     // Names for compilation reasons.
     static final String REASON_STRINGS[] = {
-            "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk", "forced-dexopt"
+            "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.
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index ac19e24..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));
 
@@ -1541,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);
             }
@@ -1671,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;
@@ -1711,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,
@@ -1763,6 +1769,7 @@
             userInfo.serialNumber = serialNumber;
             userInfo.creationTime = creationTime;
             userInfo.lastLoggedInTime = lastLoggedInTime;
+            userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint;
             userInfo.partial = partial;
             userInfo.guestToRemove = guestToRemove;
             userInfo.profileGroupId = profileGroupId;
@@ -2553,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);
@@ -2563,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);
     }
 
     /**
@@ -2838,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 d92d942..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) {
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 403a4c6..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) {}
+            }
+        }
     };
 
     // ================================================================================
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 2a57d8e..d684278 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -50,6 +50,7 @@
 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;
@@ -76,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;
@@ -130,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;
@@ -142,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;
@@ -209,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;
@@ -229,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,
@@ -815,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;
     }
@@ -869,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);
@@ -928,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;
+        }
     }
 
     /**
@@ -949,15 +1041,16 @@
         final int thumbStartX = mTmpRect.left - containingFrame.left;
         final int thumbStartY = mTmpRect.top - containingFrame.top;
 
-        // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
-        float scale = 1f;
-        int scaledTopDecor = 0;
-
         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);
 
@@ -976,16 +1069,33 @@
 
                     if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                         // We scale the width and clip to the top/left square
-                        scale = thumbWidth / (appWidth - contentInsets.left - contentInsets.right);
-                        scaledTopDecor = (int) (scale * contentInsets.top);
+                        // 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;
 
-                        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);
+                        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);
@@ -996,14 +1106,18 @@
                         mTmpFromClipRect.bottom = mTmpFromClipRect.top + thumbHeightI;
                         mTmpFromClipRect.right = mTmpFromClipRect.left + thumbWidthI;
 
-                        Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
-                        Animation translateAnim = new TranslateAnimation(thumbStartX, 0,
-                                thumbStartY - contentInsets.top, 0);
+                        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);
                 }
@@ -1031,68 +1145,12 @@
                 }
                 break;
             }
-            case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
-                // App window scaling down from full screen
-                if (freeform) {
-                    a = createAspectScaledThumbnailExitFreeformAnimationLocked(
-                            containingFrame, surfaceInsets, taskId);
-                } else {
-                    AnimationSet set = new AnimationSet(true);
-                    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);
-                    mNextAppTransitionInsets.set(contentInsets);
-
-                    if (orientation == Configuration.ORIENTATION_PORTRAIT) {
-                        // 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;
-
-                        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);
-
-                        set.addAnimation(clipAnim);
-                        set.addAnimation(scaleAnim);
-                        set.addAnimation(translateAnim);
-
-                    } else {
-                        // In landscape, we don't scale at all and only crop
-                        mTmpToClipRect.bottom = mTmpToClipRect.top + thumbHeightI;
-                        mTmpToClipRect.right = mTmpToClipRect.left + thumbWidthI;
-
-                        Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
-                        Animation translateAnim = new TranslateAnimation(0, thumbStartX, 0,
-                                thumbStartY - contentInsets.top);
-
-                        set.addAnimation(clipAnim);
-                        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,
@@ -1446,6 +1504,7 @@
                             ? WindowAnimation_activityCloseEnterAnimation
                             : WindowAnimation_activityCloseExitAnimation;
                     break;
+                case TRANSIT_DOCK_TASK_FROM_RECENTS:
                 case TRANSIT_TASK_OPEN:
                     animAttr = enter
                             ? WindowAnimation_taskOpenEnterAnimation
@@ -1504,6 +1563,8 @@
 
     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;
     }
@@ -1727,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 6225fc6..aae52e8 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -77,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;
@@ -254,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);
@@ -288,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());
     }
 
     /**
@@ -461,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/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/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index e018a4e..f76f03f 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -227,6 +227,10 @@
         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) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 708ddff..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;
@@ -799,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;
@@ -2921,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()) {
@@ -4025,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;
@@ -4990,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);
@@ -5736,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));
         }
     }
@@ -7695,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.
@@ -8276,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();
                 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 38fda1b..0866c03 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -88,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;
@@ -124,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;
@@ -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());
     }
@@ -2258,7 +2253,7 @@
         return mResizeMode;
     }
 
-    private boolean computeDragResizing() {
+    boolean computeDragResizing() {
         final Task task = getTask();
         if (task == null) {
             return false;
@@ -2288,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() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 83b6104..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;
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 909c5f2..3b0081d 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -19,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;
@@ -31,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;
@@ -688,7 +697,8 @@
                             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()) {
@@ -705,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) {
@@ -1224,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;
     }
@@ -1562,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();
@@ -1582,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/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/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index be822c8..07cc9c0 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -98,6 +98,8 @@
 
     private final PrintSpoolerCallbacks mCallbacks;
 
+    private boolean mIsLowPriority;
+
     private IPrintSpooler mRemoteInstance;
 
     private boolean mDestroyed;
@@ -110,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();
@@ -579,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/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/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/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/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 6c775b9..ea320c7 100644
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -647,15 +647,15 @@
     static String getResourceName(Resources resources, int resid) throws NotFoundException {
         boolean[] platformOut = new boolean[1];
         Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
-        String namespace;
+        String packageName;
         if (resourceInfo != null) {
             if (platformOut[0]) {
-                namespace = SdkConstants.ANDROID_NS_NAME;
+                packageName = SdkConstants.ANDROID_NS_NAME;
             } else {
-                namespace = resources.mContext.getPackageName();
-                namespace = namespace == null ? SdkConstants.APP_PREFIX : namespace;
+                packageName = resources.mContext.getPackageName();
+                packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
             }
-            return namespace + ':' + resourceInfo.getFirst().getName() + '/' +
+            return packageName + ':' + resourceInfo.getFirst().getName() + '/' +
                     resourceInfo.getSecond();
         }
         throwException(resid, null);
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/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/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) {