Merge "Remove View:hasStaticLayer()" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index eb69ed6..1117623 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23,8 +23,10 @@
     field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
     field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
+    field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
     field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
     field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
+    field public static final java.lang.String BIND_INCALL_SERVICE = "android.permission.BIND_INCALL_SERVICE";
     field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
     field public static final java.lang.String BIND_MEDIA_ROUTE_SERVICE = "android.permission.BIND_MEDIA_ROUTE_SERVICE";
     field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
@@ -278,7 +280,7 @@
     field public static final int allowParallelSyncs = 16843570; // 0x1010332
     field public static final int allowSingleTap = 16843353; // 0x1010259
     field public static final int allowTaskReparenting = 16843268; // 0x1010204
-    field public static final int allowUndo = 16844006; // 0x10104e6
+    field public static final int allowUndo = 16844005; // 0x10104e5
     field public static final int alpha = 16843551; // 0x101031f
     field public static final int alphabeticShortcut = 16843235; // 0x10101e3
     field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
@@ -299,7 +301,7 @@
     field public static final int anyDensity = 16843372; // 0x101026c
     field public static final int apduServiceBanner = 16843757; // 0x10103ed
     field public static final int apiKey = 16843281; // 0x1010211
-    field public static final int assistBlocked = 16844020; // 0x10104f4
+    field public static final int assistBlocked = 16844019; // 0x10104f3
     field public static final int author = 16843444; // 0x10102b4
     field public static final int authorities = 16842776; // 0x1010018
     field public static final int autoAdvanceViewId = 16843535; // 0x101030f
@@ -310,7 +312,7 @@
     field public static final int autoStart = 16843445; // 0x10102b5
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
-    field public static final int autoVerify = 16844010; // 0x10104ea
+    field public static final int autoVerify = 16844009; // 0x10104e9
     field public static final int background = 16842964; // 0x10100d4
     field public static final int backgroundDimAmount = 16842802; // 0x1010032
     field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -334,7 +336,7 @@
     field public static final int bottomRightRadius = 16843180; // 0x10101ac
     field public static final int breadCrumbShortTitle = 16843524; // 0x1010304
     field public static final int breadCrumbTitle = 16843523; // 0x1010303
-    field public static final int breakStrategy = 16844011; // 0x10104eb
+    field public static final int breakStrategy = 16844010; // 0x10104ea
     field public static final int bufferType = 16843086; // 0x101014e
     field public static final int button = 16843015; // 0x1010107
     field public static final int buttonBarButtonStyle = 16843567; // 0x101032f
@@ -396,7 +398,7 @@
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
     field public static final int colorBackground = 16842801; // 0x1010031
     field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
-    field public static final int colorBackgroundFloating = 16844007; // 0x10104e7
+    field public static final int colorBackgroundFloating = 16844006; // 0x10104e6
     field public static final int colorButtonNormal = 16843819; // 0x101042b
     field public static final int colorControlActivated = 16843818; // 0x101042a
     field public static final int colorControlHighlight = 16843820; // 0x101042c
@@ -505,7 +507,7 @@
     field public static final int dropDownWidth = 16843362; // 0x1010262
     field public static final int duplicateParentState = 16842985; // 0x10100e9
     field public static final int duration = 16843160; // 0x1010198
-    field public static final int dynamicResources = 16844019; // 0x10104f3
+    field public static final int dynamicResources = 16844018; // 0x10104f2
     field public static final int editTextBackground = 16843602; // 0x1010352
     field public static final int editTextColor = 16843601; // 0x1010351
     field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -517,7 +519,7 @@
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
     field public static final int enabled = 16842766; // 0x101000e
-    field public static final int end = 16843997; // 0x10104dd
+    field public static final int end = 16843996; // 0x10104dc
     field public static final int endColor = 16843166; // 0x101019e
     field public static final deprecated int endYear = 16843133; // 0x101017d
     field public static final int enterFadeDuration = 16843532; // 0x101030c
@@ -539,7 +541,7 @@
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
     field public static final int extraTension = 16843371; // 0x101026b
-    field public static final int extractNativeLibs = 16844008; // 0x10104e8
+    field public static final int extractNativeLibs = 16844007; // 0x10104e7
     field public static final int factor = 16843219; // 0x10101d3
     field public static final int fadeDuration = 16843384; // 0x1010278
     field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -653,8 +655,8 @@
     field public static final int host = 16842792; // 0x1010028
     field public static final int icon = 16842754; // 0x1010002
     field public static final int iconPreview = 16843337; // 0x1010249
-    field public static final int iconTint = 16844000; // 0x10104e0
-    field public static final int iconTintMode = 16844001; // 0x10104e1
+    field public static final int iconTint = 16843999; // 0x10104df
+    field public static final int iconTintMode = 16844000; // 0x10104e0
     field public static final int iconifiedByDefault = 16843514; // 0x10102fa
     field public static final int id = 16842960; // 0x10100d0
     field public static final int ignoreGravity = 16843263; // 0x10101ff
@@ -794,7 +796,7 @@
     field public static final int layout_x = 16843135; // 0x101017f
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
-    field public static final int leftIndents = 16844016; // 0x10104f0
+    field public static final int leftIndents = 16844015; // 0x10104ef
     field public static final int letterSpacing = 16843958; // 0x10104b6
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -817,7 +819,7 @@
     field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
     field public static final int listViewStyle = 16842868; // 0x1010074
     field public static final int listViewWhiteStyle = 16842869; // 0x1010075
-    field public static final int lockTaskMode = 16844015; // 0x10104ef
+    field public static final int lockTaskMode = 16844014; // 0x10104ee
     field public static final int logo = 16843454; // 0x10102be
     field public static final int longClickable = 16842982; // 0x10100e6
     field public static final int loopViews = 16843527; // 0x1010307
@@ -866,8 +868,8 @@
     field public static final int navigationContentDescription = 16843969; // 0x10104c1
     field public static final int navigationIcon = 16843968; // 0x10104c0
     field public static final int navigationMode = 16843471; // 0x10102cf
-    field public static final int navigationTint = 16844004; // 0x10104e4
-    field public static final int navigationTintMode = 16844005; // 0x10104e5
+    field public static final int navigationTint = 16844003; // 0x10104e3
+    field public static final int navigationTintMode = 16844004; // 0x10104e4
     field public static final int negativeButtonText = 16843254; // 0x10101f6
     field public static final int nestedScrollingEnabled = 16843830; // 0x1010436
     field public static final int nextFocusDown = 16842980; // 0x10100e4
@@ -881,7 +883,7 @@
     field public static final int numColumns = 16843032; // 0x1010118
     field public static final int numStars = 16843076; // 0x1010144
     field public static final int numbersBackgroundColor = 16843938; // 0x10104a2
-    field public static final int numbersInnerTextColor = 16843999; // 0x10104df
+    field public static final int numbersInnerTextColor = 16843998; // 0x10104de
     field public static final int numbersSelectorColor = 16843939; // 0x10104a3
     field public static final int numbersTextColor = 16843937; // 0x10104a1
     field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -899,8 +901,8 @@
     field public static final int overScrollFooter = 16843459; // 0x10102c3
     field public static final int overScrollHeader = 16843458; // 0x10102c2
     field public static final int overScrollMode = 16843457; // 0x10102c1
-    field public static final int overflowTint = 16844002; // 0x10104e2
-    field public static final int overflowTintMode = 16844003; // 0x10104e3
+    field public static final int overflowTint = 16844001; // 0x10104e1
+    field public static final int overflowTintMode = 16844002; // 0x10104e2
     field public static final int overlapAnchor = 16843874; // 0x1010462
     field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
     field public static final int packageNames = 16843649; // 0x1010381
@@ -995,7 +997,7 @@
     field public static final int readPermission = 16842759; // 0x1010007
     field public static final int recognitionService = 16843932; // 0x101049c
     field public static final int relinquishTaskIdentity = 16843894; // 0x1010476
-    field public static final int removeBeforeMRelease = 16844014; // 0x10104ee
+    field public static final int removeBeforeMRelease = 16844013; // 0x10104ed
     field public static final int reparent = 16843964; // 0x10104bc
     field public static final int reparentWithOverlay = 16843965; // 0x10104bd
     field public static final int repeatCount = 16843199; // 0x10101bf
@@ -1014,7 +1016,6 @@
     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 = 16843995; // 0x10104db
     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
@@ -1024,7 +1025,7 @@
     field public static final int reversible = 16843851; // 0x101044b
     field public static final int revisionCode = 16843989; // 0x10104d5
     field public static final int right = 16843183; // 0x10101af
-    field public static final int rightIndents = 16844017; // 0x10104f1
+    field public static final int rightIndents = 16844016; // 0x10104f0
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
     field public static final int rotation = 16843558; // 0x1010326
@@ -1100,7 +1101,7 @@
     field public static final int showAsAction = 16843481; // 0x10102d9
     field public static final int showDefault = 16843258; // 0x10101fa
     field public static final int showDividers = 16843561; // 0x1010329
-    field public static final int showForAllUsers = 16844018; // 0x10104f2
+    field public static final int showForAllUsers = 16844017; // 0x10104f1
     field public static final deprecated int showOnLockScreen = 16843721; // 0x10103c9
     field public static final int showSilent = 16843259; // 0x10101fb
     field public static final int showText = 16843949; // 0x10104ad
@@ -1130,7 +1131,7 @@
     field public static final int stackFromBottom = 16843005; // 0x10100fd
     field public static final int stackViewStyle = 16843838; // 0x101043e
     field public static final int starStyle = 16842882; // 0x1010082
-    field public static final int start = 16843996; // 0x10104dc
+    field public static final int start = 16843995; // 0x10104db
     field public static final int startColor = 16843165; // 0x101019d
     field public static final int startDelay = 16843746; // 0x10103e2
     field public static final int startOffset = 16843198; // 0x10101be
@@ -1186,7 +1187,7 @@
     field public static final int summaryColumn = 16843426; // 0x10102a2
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
-    field public static final int supportsAssistGesture = 16844012; // 0x10104ec
+    field public static final int supportsAssistGesture = 16844011; // 0x10104eb
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
     field public static final int supportsUploading = 16843419; // 0x101029b
@@ -1287,7 +1288,7 @@
     field public static final int thicknessRatio = 16843164; // 0x101019c
     field public static final int thumb = 16843074; // 0x1010142
     field public static final int thumbOffset = 16843075; // 0x1010143
-    field public static final int thumbPosition = 16844013; // 0x10104ed
+    field public static final int thumbPosition = 16844012; // 0x10104ec
     field public static final int thumbTextPadding = 16843634; // 0x1010372
     field public static final int thumbTint = 16843889; // 0x1010471
     field public static final int thumbTintMode = 16843890; // 0x1010472
@@ -1351,7 +1352,7 @@
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
     field public static final int userVisible = 16843409; // 0x1010291
-    field public static final int usesCleartextTraffic = 16844009; // 0x10104e9
+    field public static final int usesCleartextTraffic = 16844008; // 0x10104e8
     field public static final int value = 16842788; // 0x1010024
     field public static final int valueFrom = 16843486; // 0x10102de
     field public static final int valueTo = 16843487; // 0x10102df
@@ -1416,10 +1417,10 @@
     field public static final int windowExitTransition = 16843832; // 0x1010438
     field public static final int windowFrame = 16842837; // 0x1010055
     field public static final int windowFullscreen = 16843277; // 0x101020d
-    field public static final int windowHasLightStatusBar = 16843998; // 0x10104de
     field public static final int windowHideAnimation = 16842935; // 0x10100b7
     field public static final int windowIsFloating = 16842839; // 0x1010057
     field public static final int windowIsTranslucent = 16842840; // 0x1010058
+    field public static final int windowLightStatusBar = 16843997; // 0x10104dd
     field public static final int windowMinWidthMajor = 16843606; // 0x1010356
     field public static final int windowMinWidthMinor = 16843607; // 0x1010357
     field public static final int windowNoDisplay = 16843294; // 0x101021e
@@ -2104,6 +2105,7 @@
     field public static final int Theme_Material_DayNight_DarkActionBar = 16974549; // 0x10302d5
     field public static final int Theme_Material_DayNight_Dialog = 16974550; // 0x10302d6
     field public static final int Theme_Material_DayNight_DialogWhenLarge = 16974556; // 0x10302dc
+    field public static final int Theme_Material_DayNight_DialogWhenLarge_DarkActionBar = 16974568; // 0x10302e8
     field public static final int Theme_Material_DayNight_DialogWhenLarge_NoActionBar = 16974557; // 0x10302dd
     field public static final int Theme_Material_DayNight_Dialog_Alert = 16974551; // 0x10302d7
     field public static final int Theme_Material_DayNight_Dialog_MinWidth = 16974552; // 0x10302d8
@@ -2128,6 +2130,7 @@
     field public static final int Theme_Material_Light_DarkActionBar = 16974392; // 0x1030238
     field public static final int Theme_Material_Light_Dialog = 16974393; // 0x1030239
     field public static final int Theme_Material_Light_DialogWhenLarge = 16974399; // 0x103023f
+    field public static final int Theme_Material_Light_DialogWhenLarge_DarkActionBar = 16974567; // 0x10302e7
     field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974400; // 0x1030240
     field public static final int Theme_Material_Light_Dialog_Alert = 16974394; // 0x103023a
     field public static final int Theme_Material_Light_Dialog_MinWidth = 16974395; // 0x103023b
@@ -5727,6 +5730,7 @@
     method public int getPasswordMinimumSymbols(android.content.ComponentName);
     method public int getPasswordMinimumUpperCase(android.content.ComponentName);
     method public int getPasswordQuality(android.content.ComponentName);
+    method public int getPermissionPolicy(android.content.ComponentName);
     method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
     method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName);
     method public boolean getScreenCaptureDisabled(android.content.ComponentName);
@@ -5779,8 +5783,11 @@
     method public void setPasswordMinimumSymbols(android.content.ComponentName, int);
     method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
     method public void setPasswordQuality(android.content.ComponentName, int);
+    method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean);
+    method public void setPermissionPolicy(android.content.ComponentName, int);
     method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>);
     method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>);
+    method public void setPreferredSetupActivity(android.content.ComponentName, android.content.ComponentName);
     method public void setProfileEnabled(android.content.ComponentName);
     method public void setProfileName(android.content.ComponentName, java.lang.String);
     method public void setRecommendedGlobalProxy(android.content.ComponentName, android.net.ProxyInfo);
@@ -5866,6 +5873,9 @@
     field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000
     field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
     field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
+    field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2
+    field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1
+    field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
     field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
     field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
@@ -9399,6 +9409,7 @@
     field public static final int GET_SIGNATURES = 64; // 0x40
     field public static final int GET_UNINSTALLED_PACKAGES = 8192; // 0x2000
     field public static final int GET_URI_PERMISSION_PATTERNS = 2048; // 0x800
+    field public static final int MATCH_ALL = 131072; // 0x20000
     field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
     field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
     field public static final int PERMISSION_DENIED = -1; // 0xffffffff
@@ -11183,6 +11194,8 @@
     method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint);
+    method public void drawTextRun(char[], int, int, int, int, float, float, boolean, android.graphics.Paint);
+    method public void drawTextRun(java.lang.CharSequence, int, int, int, int, float, float, boolean, android.graphics.Paint);
     method public void drawVertices(android.graphics.Canvas.VertexMode, int, float[], int, float[], int, int[], int, short[], int, int, android.graphics.Paint);
     method public boolean getClipBounds(android.graphics.Rect);
     method public final android.graphics.Rect getClipBounds();
@@ -13221,6 +13234,7 @@
     field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_TRANSLATION;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_RADIAL_DISTORTION;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REPROCESS_MAX_CAPTURE_STALL;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_INPUT_STREAMS;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC;
@@ -28521,10 +28535,9 @@
     method public java.lang.String getKeystoreAlias();
     method public int getPurposes();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
     method public boolean isEncryptionRequired();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isRandomizedEncryptionRequired();
+    method public boolean isUserAuthenticationRequired();
   }
 
   public static class KeyGeneratorSpec.Builder {
@@ -28534,7 +28547,6 @@
     method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...);
     method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
     method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(boolean);
-    method public android.security.KeyGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
     method public android.security.KeyGeneratorSpec.Builder setKeySize(int);
     method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
     method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
@@ -28542,8 +28554,8 @@
     method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
     method public android.security.KeyGeneratorSpec.Builder setPurposes(int);
     method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
+    method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
     method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
-    method public android.security.KeyGeneratorSpec.Builder setUserAuthenticators(int);
   }
 
   public class KeyNotYetValidException extends java.security.InvalidKeyException {
@@ -28571,10 +28583,9 @@
     method public java.util.Date getStartDate();
     method public javax.security.auth.x500.X500Principal getSubjectDN();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
     method public boolean isEncryptionRequired();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isRandomizedEncryptionRequired();
+    method public boolean isUserAuthenticationRequired();
   }
 
   public static final class KeyPairGeneratorSpec.Builder {
@@ -28587,7 +28598,6 @@
     method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
     method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
     method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
-    method public android.security.KeyPairGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
     method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
     method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
     method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
@@ -28600,8 +28610,8 @@
     method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...);
     method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
     method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+    method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
     method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
-    method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticators(int);
   }
 
   public abstract class KeyStoreKeyProperties {
@@ -28626,14 +28636,6 @@
   public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
   }
 
-  public static abstract class KeyStoreKeyProperties.UserAuthenticator {
-    field public static final int FINGERPRINT_READER = 2; // 0x2
-    field public static final int LOCK_SCREEN = 1; // 0x1
-  }
-
-  public static abstract class KeyStoreKeyProperties.UserAuthenticatorEnum implements java.lang.annotation.Annotation {
-  }
-
   public class KeyStoreKeySpec implements java.security.spec.KeySpec {
     method public java.lang.String[] getBlockModes();
     method public java.lang.String[] getDigests();
@@ -28646,15 +28648,15 @@
     method public int getOrigin();
     method public int getPurposes();
     method public java.lang.String[] getSignaturePaddings();
-    method public int getTeeEnforcedUserAuthenticators();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isTeeBacked();
+    method public boolean isUserAuthenticationRequired();
+    method public boolean isUserAuthenticationRequirementTeeEnforced();
   }
 
   public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
     method public java.lang.String[] getBlockModes();
+    method public android.content.Context getContext();
     method public java.lang.String[] getDigests();
     method public java.lang.String[] getEncryptionPaddings();
     method public java.util.Date getKeyValidityForConsumptionEnd();
@@ -28663,11 +28665,10 @@
     method public int getPurposes();
     method public java.lang.String[] getSignaturePaddings();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
     method public boolean isDigestsSpecified();
     method public boolean isEncryptionRequired();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isRandomizedEncryptionRequired();
+    method public boolean isUserAuthenticationRequired();
   }
 
   public static final class KeyStoreParameter.Builder {
@@ -28677,7 +28678,6 @@
     method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...);
     method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...);
     method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
-    method public android.security.KeyStoreParameter.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
     method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date);
     method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date);
     method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date);
@@ -28685,8 +28685,8 @@
     method public android.security.KeyStoreParameter.Builder setPurposes(int);
     method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean);
     method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...);
+    method public android.security.KeyStoreParameter.Builder setUserAuthenticationRequired(boolean);
     method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int);
-    method public android.security.KeyStoreParameter.Builder setUserAuthenticators(int);
   }
 
   public class NetworkSecurityPolicy {
@@ -30427,7 +30427,6 @@
   public static abstract class InCallService.VideoCall {
     ctor public InCallService.VideoCall();
     method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback);
-    method public abstract void unregisterCallback();
     method public abstract void requestCallDataUsage();
     method public abstract void requestCameraCapabilities();
     method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile);
@@ -30438,6 +30437,7 @@
     method public abstract void setPauseImage(java.lang.String);
     method public abstract void setPreviewSurface(android.view.Surface);
     method public abstract void setZoom(float);
+    method public abstract void unregisterCallback();
   }
 
   public static abstract class InCallService.VideoCall.Callback {
@@ -33992,6 +33992,7 @@
     method public static void readEvents(int[], java.util.Collection<android.util.EventLog.Event>) throws java.io.IOException;
     method public static int writeEvent(int, int);
     method public static int writeEvent(int, long);
+    method public static int writeEvent(int, float);
     method public static int writeEvent(int, java.lang.String);
     method public static int writeEvent(int, java.lang.Object...);
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index b8c7fa2..7210666 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -351,7 +351,7 @@
     field public static final int allowParallelSyncs = 16843570; // 0x1010332
     field public static final int allowSingleTap = 16843353; // 0x1010259
     field public static final int allowTaskReparenting = 16843268; // 0x1010204
-    field public static final int allowUndo = 16844006; // 0x10104e6
+    field public static final int allowUndo = 16844005; // 0x10104e5
     field public static final int alpha = 16843551; // 0x101031f
     field public static final int alphabeticShortcut = 16843235; // 0x10101e3
     field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
@@ -372,7 +372,7 @@
     field public static final int anyDensity = 16843372; // 0x101026c
     field public static final int apduServiceBanner = 16843757; // 0x10103ed
     field public static final int apiKey = 16843281; // 0x1010211
-    field public static final int assistBlocked = 16844020; // 0x10104f4
+    field public static final int assistBlocked = 16844019; // 0x10104f3
     field public static final int author = 16843444; // 0x10102b4
     field public static final int authorities = 16842776; // 0x1010018
     field public static final int autoAdvanceViewId = 16843535; // 0x101030f
@@ -383,7 +383,7 @@
     field public static final int autoStart = 16843445; // 0x10102b5
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
-    field public static final int autoVerify = 16844010; // 0x10104ea
+    field public static final int autoVerify = 16844009; // 0x10104e9
     field public static final int background = 16842964; // 0x10100d4
     field public static final int backgroundDimAmount = 16842802; // 0x1010032
     field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -407,7 +407,7 @@
     field public static final int bottomRightRadius = 16843180; // 0x10101ac
     field public static final int breadCrumbShortTitle = 16843524; // 0x1010304
     field public static final int breadCrumbTitle = 16843523; // 0x1010303
-    field public static final int breakStrategy = 16844011; // 0x10104eb
+    field public static final int breakStrategy = 16844010; // 0x10104ea
     field public static final int bufferType = 16843086; // 0x101014e
     field public static final int button = 16843015; // 0x1010107
     field public static final int buttonBarButtonStyle = 16843567; // 0x101032f
@@ -469,7 +469,7 @@
     field public static final int colorActivatedHighlight = 16843664; // 0x1010390
     field public static final int colorBackground = 16842801; // 0x1010031
     field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
-    field public static final int colorBackgroundFloating = 16844007; // 0x10104e7
+    field public static final int colorBackgroundFloating = 16844006; // 0x10104e6
     field public static final int colorButtonNormal = 16843819; // 0x101042b
     field public static final int colorControlActivated = 16843818; // 0x101042a
     field public static final int colorControlHighlight = 16843820; // 0x101042c
@@ -578,7 +578,7 @@
     field public static final int dropDownWidth = 16843362; // 0x1010262
     field public static final int duplicateParentState = 16842985; // 0x10100e9
     field public static final int duration = 16843160; // 0x1010198
-    field public static final int dynamicResources = 16844019; // 0x10104f3
+    field public static final int dynamicResources = 16844018; // 0x10104f2
     field public static final int editTextBackground = 16843602; // 0x1010352
     field public static final int editTextColor = 16843601; // 0x1010351
     field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -590,7 +590,7 @@
     field public static final int ellipsize = 16842923; // 0x10100ab
     field public static final int ems = 16843096; // 0x1010158
     field public static final int enabled = 16842766; // 0x101000e
-    field public static final int end = 16843997; // 0x10104dd
+    field public static final int end = 16843996; // 0x10104dc
     field public static final int endColor = 16843166; // 0x101019e
     field public static final deprecated int endYear = 16843133; // 0x101017d
     field public static final int enterFadeDuration = 16843532; // 0x101030c
@@ -612,7 +612,7 @@
     field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
     field public static final int exported = 16842768; // 0x1010010
     field public static final int extraTension = 16843371; // 0x101026b
-    field public static final int extractNativeLibs = 16844008; // 0x10104e8
+    field public static final int extractNativeLibs = 16844007; // 0x10104e7
     field public static final int factor = 16843219; // 0x10101d3
     field public static final int fadeDuration = 16843384; // 0x1010278
     field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -726,8 +726,8 @@
     field public static final int host = 16842792; // 0x1010028
     field public static final int icon = 16842754; // 0x1010002
     field public static final int iconPreview = 16843337; // 0x1010249
-    field public static final int iconTint = 16844000; // 0x10104e0
-    field public static final int iconTintMode = 16844001; // 0x10104e1
+    field public static final int iconTint = 16843999; // 0x10104df
+    field public static final int iconTintMode = 16844000; // 0x10104e0
     field public static final int iconifiedByDefault = 16843514; // 0x10102fa
     field public static final int id = 16842960; // 0x10100d0
     field public static final int ignoreGravity = 16843263; // 0x10101ff
@@ -867,7 +867,7 @@
     field public static final int layout_x = 16843135; // 0x101017f
     field public static final int layout_y = 16843136; // 0x1010180
     field public static final int left = 16843181; // 0x10101ad
-    field public static final int leftIndents = 16844016; // 0x10104f0
+    field public static final int leftIndents = 16844015; // 0x10104ef
     field public static final int letterSpacing = 16843958; // 0x10104b6
     field public static final int lineSpacingExtra = 16843287; // 0x1010217
     field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -890,7 +890,7 @@
     field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
     field public static final int listViewStyle = 16842868; // 0x1010074
     field public static final int listViewWhiteStyle = 16842869; // 0x1010075
-    field public static final int lockTaskMode = 16844015; // 0x10104ef
+    field public static final int lockTaskMode = 16844014; // 0x10104ee
     field public static final int logo = 16843454; // 0x10102be
     field public static final int longClickable = 16842982; // 0x10100e6
     field public static final int loopViews = 16843527; // 0x1010307
@@ -939,8 +939,8 @@
     field public static final int navigationContentDescription = 16843969; // 0x10104c1
     field public static final int navigationIcon = 16843968; // 0x10104c0
     field public static final int navigationMode = 16843471; // 0x10102cf
-    field public static final int navigationTint = 16844004; // 0x10104e4
-    field public static final int navigationTintMode = 16844005; // 0x10104e5
+    field public static final int navigationTint = 16844003; // 0x10104e3
+    field public static final int navigationTintMode = 16844004; // 0x10104e4
     field public static final int negativeButtonText = 16843254; // 0x10101f6
     field public static final int nestedScrollingEnabled = 16843830; // 0x1010436
     field public static final int nextFocusDown = 16842980; // 0x10100e4
@@ -954,7 +954,7 @@
     field public static final int numColumns = 16843032; // 0x1010118
     field public static final int numStars = 16843076; // 0x1010144
     field public static final int numbersBackgroundColor = 16843938; // 0x10104a2
-    field public static final int numbersInnerTextColor = 16843999; // 0x10104df
+    field public static final int numbersInnerTextColor = 16843998; // 0x10104de
     field public static final int numbersSelectorColor = 16843939; // 0x10104a3
     field public static final int numbersTextColor = 16843937; // 0x10104a1
     field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -972,8 +972,8 @@
     field public static final int overScrollFooter = 16843459; // 0x10102c3
     field public static final int overScrollHeader = 16843458; // 0x10102c2
     field public static final int overScrollMode = 16843457; // 0x10102c1
-    field public static final int overflowTint = 16844002; // 0x10104e2
-    field public static final int overflowTintMode = 16844003; // 0x10104e3
+    field public static final int overflowTint = 16844001; // 0x10104e1
+    field public static final int overflowTintMode = 16844002; // 0x10104e2
     field public static final int overlapAnchor = 16843874; // 0x1010462
     field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
     field public static final int packageNames = 16843649; // 0x1010381
@@ -1068,7 +1068,7 @@
     field public static final int readPermission = 16842759; // 0x1010007
     field public static final int recognitionService = 16843932; // 0x101049c
     field public static final int relinquishTaskIdentity = 16843894; // 0x1010476
-    field public static final int removeBeforeMRelease = 16844014; // 0x10104ee
+    field public static final int removeBeforeMRelease = 16844013; // 0x10104ed
     field public static final int reparent = 16843964; // 0x10104bc
     field public static final int reparentWithOverlay = 16843965; // 0x10104bd
     field public static final int repeatCount = 16843199; // 0x10101bf
@@ -1087,7 +1087,6 @@
     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 = 16843995; // 0x10104db
     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
@@ -1097,7 +1096,7 @@
     field public static final int reversible = 16843851; // 0x101044b
     field public static final int revisionCode = 16843989; // 0x10104d5
     field public static final int right = 16843183; // 0x10101af
-    field public static final int rightIndents = 16844017; // 0x10104f1
+    field public static final int rightIndents = 16844016; // 0x10104f0
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
     field public static final int rotation = 16843558; // 0x1010326
@@ -1177,7 +1176,7 @@
     field public static final int showAsAction = 16843481; // 0x10102d9
     field public static final int showDefault = 16843258; // 0x10101fa
     field public static final int showDividers = 16843561; // 0x1010329
-    field public static final int showForAllUsers = 16844018; // 0x10104f2
+    field public static final int showForAllUsers = 16844017; // 0x10104f1
     field public static final deprecated int showOnLockScreen = 16843721; // 0x10103c9
     field public static final int showSilent = 16843259; // 0x10101fb
     field public static final int showText = 16843949; // 0x10104ad
@@ -1207,7 +1206,7 @@
     field public static final int stackFromBottom = 16843005; // 0x10100fd
     field public static final int stackViewStyle = 16843838; // 0x101043e
     field public static final int starStyle = 16842882; // 0x1010082
-    field public static final int start = 16843996; // 0x10104dc
+    field public static final int start = 16843995; // 0x10104db
     field public static final int startColor = 16843165; // 0x101019d
     field public static final int startDelay = 16843746; // 0x10103e2
     field public static final int startOffset = 16843198; // 0x10101be
@@ -1263,7 +1262,7 @@
     field public static final int summaryColumn = 16843426; // 0x10102a2
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
-    field public static final int supportsAssistGesture = 16844012; // 0x10104ec
+    field public static final int supportsAssistGesture = 16844011; // 0x10104eb
     field public static final int supportsRtl = 16843695; // 0x10103af
     field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
     field public static final int supportsUploading = 16843419; // 0x101029b
@@ -1364,7 +1363,7 @@
     field public static final int thicknessRatio = 16843164; // 0x101019c
     field public static final int thumb = 16843074; // 0x1010142
     field public static final int thumbOffset = 16843075; // 0x1010143
-    field public static final int thumbPosition = 16844013; // 0x10104ed
+    field public static final int thumbPosition = 16844012; // 0x10104ec
     field public static final int thumbTextPadding = 16843634; // 0x1010372
     field public static final int thumbTint = 16843889; // 0x1010471
     field public static final int thumbTintMode = 16843890; // 0x1010472
@@ -1428,7 +1427,7 @@
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
     field public static final int userVisible = 16843409; // 0x1010291
-    field public static final int usesCleartextTraffic = 16844009; // 0x10104e9
+    field public static final int usesCleartextTraffic = 16844008; // 0x10104e8
     field public static final int value = 16842788; // 0x1010024
     field public static final int valueFrom = 16843486; // 0x10102de
     field public static final int valueTo = 16843487; // 0x10102df
@@ -1493,10 +1492,10 @@
     field public static final int windowExitTransition = 16843832; // 0x1010438
     field public static final int windowFrame = 16842837; // 0x1010055
     field public static final int windowFullscreen = 16843277; // 0x101020d
-    field public static final int windowHasLightStatusBar = 16843998; // 0x10104de
     field public static final int windowHideAnimation = 16842935; // 0x10100b7
     field public static final int windowIsFloating = 16842839; // 0x1010057
     field public static final int windowIsTranslucent = 16842840; // 0x1010058
+    field public static final int windowLightStatusBar = 16843997; // 0x10104dd
     field public static final int windowMinWidthMajor = 16843606; // 0x1010356
     field public static final int windowMinWidthMinor = 16843607; // 0x1010357
     field public static final int windowNoDisplay = 16843294; // 0x101021e
@@ -2184,6 +2183,7 @@
     field public static final int Theme_Material_DayNight_DarkActionBar = 16974549; // 0x10302d5
     field public static final int Theme_Material_DayNight_Dialog = 16974550; // 0x10302d6
     field public static final int Theme_Material_DayNight_DialogWhenLarge = 16974556; // 0x10302dc
+    field public static final int Theme_Material_DayNight_DialogWhenLarge_DarkActionBar = 16974568; // 0x10302e8
     field public static final int Theme_Material_DayNight_DialogWhenLarge_NoActionBar = 16974557; // 0x10302dd
     field public static final int Theme_Material_DayNight_Dialog_Alert = 16974551; // 0x10302d7
     field public static final int Theme_Material_DayNight_Dialog_MinWidth = 16974552; // 0x10302d8
@@ -2208,6 +2208,7 @@
     field public static final int Theme_Material_Light_DarkActionBar = 16974392; // 0x1030238
     field public static final int Theme_Material_Light_Dialog = 16974393; // 0x1030239
     field public static final int Theme_Material_Light_DialogWhenLarge = 16974399; // 0x103023f
+    field public static final int Theme_Material_Light_DialogWhenLarge_DarkActionBar = 16974567; // 0x10302e7
     field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974400; // 0x1030240
     field public static final int Theme_Material_Light_Dialog_Alert = 16974394; // 0x103023a
     field public static final int Theme_Material_Light_Dialog_MinWidth = 16974395; // 0x103023b
@@ -5826,6 +5827,7 @@
     method public int getPasswordMinimumSymbols(android.content.ComponentName);
     method public int getPasswordMinimumUpperCase(android.content.ComponentName);
     method public int getPasswordQuality(android.content.ComponentName);
+    method public int getPermissionPolicy(android.content.ComponentName);
     method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
     method public java.util.List<java.lang.String> getPermittedAccessibilityServices(int);
     method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName);
@@ -5884,8 +5886,11 @@
     method public void setPasswordMinimumSymbols(android.content.ComponentName, int);
     method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
     method public void setPasswordQuality(android.content.ComponentName, int);
+    method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean);
+    method public void setPermissionPolicy(android.content.ComponentName, int);
     method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>);
     method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>);
+    method public void setPreferredSetupActivity(android.content.ComponentName, android.content.ComponentName);
     method public void setProfileEnabled(android.content.ComponentName);
     method public void setProfileName(android.content.ComponentName, java.lang.String);
     method public void setRecommendedGlobalProxy(android.content.ComponentName, android.net.ProxyInfo);
@@ -5976,6 +5981,9 @@
     field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000
     field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
     field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
+    field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2
+    field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1
+    field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
     field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
     field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
@@ -9694,6 +9702,7 @@
     field public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; // 0xffffff99
     field public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; // 0xffffff9a
     field public static final int INSTALL_SUCCEEDED = 1; // 0x1
+    field public static final int MATCH_ALL = 131072; // 0x20000
     field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
     field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
     field public static final int PERMISSION_DENIED = -1; // 0xffffffff
@@ -11478,6 +11487,8 @@
     method public void drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint);
     method public void drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint);
     method public void drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint);
+    method public void drawTextRun(char[], int, int, int, int, float, float, boolean, android.graphics.Paint);
+    method public void drawTextRun(java.lang.CharSequence, int, int, int, int, float, float, boolean, android.graphics.Paint);
     method public void drawVertices(android.graphics.Canvas.VertexMode, int, float[], int, float[], int, int[], int, short[], int, int, android.graphics.Paint);
     method public boolean getClipBounds(android.graphics.Rect);
     method public final android.graphics.Rect getClipBounds();
@@ -13521,6 +13532,7 @@
     field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_TRANSLATION;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_RADIAL_DISTORTION;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
+    field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REPROCESS_MAX_CAPTURE_STALL;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_INPUT_STREAMS;
     field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC;
@@ -30528,10 +30540,9 @@
     method public java.lang.String getKeystoreAlias();
     method public int getPurposes();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
     method public boolean isEncryptionRequired();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isRandomizedEncryptionRequired();
+    method public boolean isUserAuthenticationRequired();
   }
 
   public static class KeyGeneratorSpec.Builder {
@@ -30541,7 +30552,6 @@
     method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...);
     method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
     method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(boolean);
-    method public android.security.KeyGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
     method public android.security.KeyGeneratorSpec.Builder setKeySize(int);
     method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
     method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
@@ -30549,8 +30559,8 @@
     method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
     method public android.security.KeyGeneratorSpec.Builder setPurposes(int);
     method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
+    method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
     method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
-    method public android.security.KeyGeneratorSpec.Builder setUserAuthenticators(int);
   }
 
   public class KeyNotYetValidException extends java.security.InvalidKeyException {
@@ -30578,10 +30588,9 @@
     method public java.util.Date getStartDate();
     method public javax.security.auth.x500.X500Principal getSubjectDN();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
     method public boolean isEncryptionRequired();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isRandomizedEncryptionRequired();
+    method public boolean isUserAuthenticationRequired();
   }
 
   public static final class KeyPairGeneratorSpec.Builder {
@@ -30594,7 +30603,6 @@
     method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
     method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
     method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
-    method public android.security.KeyPairGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
     method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
     method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
     method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
@@ -30607,8 +30615,8 @@
     method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...);
     method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
     method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+    method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
     method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
-    method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticators(int);
   }
 
   public abstract class KeyStoreKeyProperties {
@@ -30633,14 +30641,6 @@
   public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
   }
 
-  public static abstract class KeyStoreKeyProperties.UserAuthenticator {
-    field public static final int FINGERPRINT_READER = 2; // 0x2
-    field public static final int LOCK_SCREEN = 1; // 0x1
-  }
-
-  public static abstract class KeyStoreKeyProperties.UserAuthenticatorEnum implements java.lang.annotation.Annotation {
-  }
-
   public class KeyStoreKeySpec implements java.security.spec.KeySpec {
     method public java.lang.String[] getBlockModes();
     method public java.lang.String[] getDigests();
@@ -30653,15 +30653,15 @@
     method public int getOrigin();
     method public int getPurposes();
     method public java.lang.String[] getSignaturePaddings();
-    method public int getTeeEnforcedUserAuthenticators();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isTeeBacked();
+    method public boolean isUserAuthenticationRequired();
+    method public boolean isUserAuthenticationRequirementTeeEnforced();
   }
 
   public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
     method public java.lang.String[] getBlockModes();
+    method public android.content.Context getContext();
     method public java.lang.String[] getDigests();
     method public java.lang.String[] getEncryptionPaddings();
     method public java.util.Date getKeyValidityForConsumptionEnd();
@@ -30670,11 +30670,10 @@
     method public int getPurposes();
     method public java.lang.String[] getSignaturePaddings();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public int getUserAuthenticators();
     method public boolean isDigestsSpecified();
     method public boolean isEncryptionRequired();
-    method public boolean isInvalidatedOnNewFingerprintEnrolled();
     method public boolean isRandomizedEncryptionRequired();
+    method public boolean isUserAuthenticationRequired();
   }
 
   public static final class KeyStoreParameter.Builder {
@@ -30684,7 +30683,6 @@
     method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...);
     method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...);
     method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
-    method public android.security.KeyStoreParameter.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
     method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date);
     method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date);
     method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date);
@@ -30692,8 +30690,8 @@
     method public android.security.KeyStoreParameter.Builder setPurposes(int);
     method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean);
     method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...);
+    method public android.security.KeyStoreParameter.Builder setUserAuthenticationRequired(boolean);
     method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int);
-    method public android.security.KeyStoreParameter.Builder setUserAuthenticators(int);
   }
 
   public class NetworkSecurityPolicy {
@@ -32544,7 +32542,6 @@
   public static abstract class InCallService.VideoCall {
     ctor public InCallService.VideoCall();
     method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback);
-    method public abstract void unregisterCallback();
     method public abstract void requestCallDataUsage();
     method public abstract void requestCameraCapabilities();
     method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile);
@@ -32555,6 +32552,7 @@
     method public abstract void setPauseImage(java.lang.String);
     method public abstract void setPreviewSurface(android.view.Surface);
     method public abstract void setZoom(float);
+    method public abstract void unregisterCallback();
   }
 
   public static abstract class InCallService.VideoCall.Callback {
@@ -36196,6 +36194,7 @@
     method public static void readEvents(int[], java.util.Collection<android.util.EventLog.Event>) throws java.io.IOException;
     method public static int writeEvent(int, int);
     method public static int writeEvent(int, long);
+    method public static int writeEvent(int, float);
     method public static int writeEvent(int, java.lang.String);
     method public static int writeEvent(int, java.lang.Object...);
   }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b11c509..a71a258 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2521,6 +2521,15 @@
             return true;
         }
 
+        case UPDATE_PREFERRED_SETUP_ACTIVITY_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            ComponentName preferredActivity = ComponentName.readFromParcel(data);
+            int userId = data.readInt();
+            updatePreferredSetupActivity(preferredActivity, userId);
+            reply.writeNoException();
+            return true;
+        }
+
         case GET_PACKAGE_PROCESS_STATE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String pkg = data.readString();
@@ -5821,6 +5830,20 @@
     }
 
     @Override
+    public void updatePreferredSetupActivity(ComponentName preferredActivity, int userId)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        ComponentName.writeToParcel(preferredActivity, data);
+        data.writeInt(userId);
+        mRemote.transact(UPDATE_PREFERRED_SETUP_ACTIVITY_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
     public int getPackageProcessState(String packageName) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 16a2430..6e511f3 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -79,6 +79,7 @@
 import dalvik.system.VMRuntime;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.SomeArgs;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.UserIcons;
 
@@ -2054,8 +2055,7 @@
     /** {@hide} */
     private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
             Handler.Callback {
-        private static final int MSG_STARTED = 1;
-        private static final int MSG_STATUS_CHANGED = 2;
+        private static final int MSG_STATUS_CHANGED = 1;
 
         final MoveCallback mCallback;
         final Handler mHandler;
@@ -2067,26 +2067,25 @@
 
         @Override
         public boolean handleMessage(Message msg) {
-            final int moveId = msg.arg1;
             switch (msg.what) {
-                case MSG_STARTED:
-                    mCallback.onStarted(moveId, (String) msg.obj);
-                    return true;
                 case MSG_STATUS_CHANGED:
-                    mCallback.onStatusChanged(moveId, msg.arg2, (long) msg.obj);
+                    final SomeArgs args = (SomeArgs) msg.obj;
+                    mCallback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
+                            (long) args.arg4);
+                    args.recycle();
                     return true;
             }
             return false;
         }
 
         @Override
-        public void onStarted(int moveId, String title) {
-            mHandler.obtainMessage(MSG_STARTED, moveId, 0, title).sendToTarget();
-        }
-
-        @Override
-        public void onStatusChanged(int moveId, int status, long estMillis) {
-            mHandler.obtainMessage(MSG_STATUS_CHANGED, moveId, status, estMillis).sendToTarget();
+        public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
+            final SomeArgs args = SomeArgs.obtain();
+            args.argi1 = moveId;
+            args.arg2 = moveTitle;
+            args.argi3 = status;
+            args.arg4 = estMillis;
+            mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
         }
     }
 
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 00558fe..5829fbe 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -496,6 +496,8 @@
             throws RemoteException;
     public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException;
     public void updateDeviceOwner(String packageName) throws RemoteException;
+    public void updatePreferredSetupActivity(ComponentName preferredActivity, int userId)
+            throws RemoteException;
 
     public int getPackageProcessState(String packageName) throws RemoteException;
 
@@ -839,4 +841,5 @@
     int GET_PACKAGE_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+293;
     int SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+294;
     int UPDATE_DEVICE_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+295;
+    int UPDATE_PREFERRED_SETUP_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+296;
 }
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index ce5306f..31d1ab7 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -17,6 +17,7 @@
 
 package android.app;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.os.Binder;
 import android.os.RemoteException;
@@ -27,6 +28,9 @@
 
 import com.android.internal.statusbar.IStatusBarService;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Allows an app to control the status bar.
  *
@@ -59,6 +63,23 @@
             | DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK
             | DISABLE_SEARCH;
 
+    /**
+     * Flag to disable quick settings.
+     *
+     * Setting this flag disables quick settings completely, but does not disable expanding the
+     * notification shade.
+     */
+    public static final int DISABLE2_QUICK_SETTINGS = 0x00000001;
+
+    public static final int DISABLE2_NONE = 0x00000000;
+
+    public static final int DISABLE2_MASK = DISABLE2_QUICK_SETTINGS;
+
+    @IntDef(flag = true,
+            value = {DISABLE2_NONE, DISABLE2_MASK, DISABLE2_QUICK_SETTINGS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Disable2Flags {}
+
     public static final int NAVIGATION_HINT_BACK_ALT      = 1 << 0;
     public static final int NAVIGATION_HINT_IME_SHOWN     = 1 << 1;
 
@@ -103,7 +124,25 @@
             throw new RuntimeException(ex);
         }
     }
-    
+
+    /**
+     * Disable additional status bar features. Pass the bitwise-or of the DISABLE2_* flags.
+     * To re-enable everything, pass {@link #DISABLE_NONE}.
+     *
+     * Warning: Only pass DISABLE2_* flags into this function, do not use DISABLE_* flags.
+     */
+    public void disable2(@Disable2Flags int what) {
+        try {
+            final IStatusBarService svc = getService();
+            if (svc != null) {
+                svc.disable2(what, mToken, mContext.getPackageName());
+            }
+        } catch (RemoteException ex) {
+            // system process is dead anyway.
+            throw new RuntimeException(ex);
+        }
+    }
+
     /**
      * Expand the notifications panel.
      */
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 47133d4..cf9813f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -807,6 +807,24 @@
     public static final String ACTION_SYSTEM_UPDATE_POLICY_CHANGED
             = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
 
+    /**
+     * Permission policy to prompt user for new permission requests for runtime permissions.
+     * Already granted or denied permissions are not affected by this.
+     */
+    public static final int PERMISSION_POLICY_PROMPT = 0;
+
+    /**
+     * Permission policy to always grant new permission requests for runtime permissions.
+     * Already granted or denied permissions are not affected by this.
+     */
+    public static final int PERMISSION_POLICY_AUTO_GRANT = 1;
+
+    /**
+     * Permission policy to always deny new permission requests for runtime permissions.
+     * Already granted or denied permissions are not affected by this.
+     */
+    public static final int PERMISSION_POLICY_AUTO_DENY = 2;
+
 
     /**
      * Return true if the given administrator component is currently
@@ -4325,4 +4343,75 @@
             }
         }
     }
+
+    /**
+     * Called by a device initializer to set the activity to be launched on device boot or after a
+     * user switch during user setup. This activity will be started regardless of the priority of
+     * other 'home' activities. Once user setup is complete, the preferred setup activity will be
+     * ignored.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param activity The Activity to be started by default during user setup.
+     */
+    public void setPreferredSetupActivity(ComponentName admin, ComponentName activity) {
+        try {
+            mService.setPreferredSetupActivity(admin, activity);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Failed talking with device policy service", re);
+        }
+    }
+
+    /**
+     * Called by profile or device owners to set the default response for future runtime permission
+     * requests by applications. The policy can allow for normal operation which prompts the
+     * user to grant a permission, or can allow automatic granting or denying of runtime
+     * permission requests by an application. This also applies to new permissions declared by app
+     * updates.
+     * @param admin Which profile or device owner this request is associated with.
+     * @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
+     * {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}.
+     */
+    public void setPermissionPolicy(ComponentName admin, int policy) {
+        try {
+            mService.setPermissionPolicy(admin, policy);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Failed talking with device policy service", re);
+        }
+    }
+
+    /**
+     * Returns the current runtime permission policy set by the device or profile owner. The
+     * default is {@link #PERMISSION_POLICY_PROMPT}.
+     * @param admin Which profile or device owner this request is associated with.
+     * @return the current policy for future permission requests.
+     */
+    public int getPermissionPolicy(ComponentName admin) {
+        try {
+            return mService.getPermissionPolicy(admin);
+        } catch (RemoteException re) {
+            return PERMISSION_POLICY_PROMPT;
+        }
+    }
+
+    /**
+     * Grants or revokes a runtime permission to a specific application so that the user
+     * does not have to be prompted. This might affect all permissions in a group that the
+     * runtime permission belongs to. This method can only be called by a profile or device
+     * owner.
+     * @param admin Which profile or device owner this request is associated with.
+     * @param packageName The application to grant or revoke a permission to.
+     * @param permission The permission to grant or revoke.
+     * @param granted Whether or not to grant the permission. If false, all permissions in the
+     * associated permission group will be denied.
+     * @return whether the permission was successfully granted or revoked
+     */
+    public boolean setPermissionGranted(ComponentName admin, String packageName,
+            String permission, boolean granted) {
+        try {
+            return mService.setPermissionGranted(admin, packageName, permission, granted);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Failed talking with device policy service", re);
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 087fc88..833bc00 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -216,6 +216,8 @@
     String getDeviceInitializer();
     ComponentName getDeviceInitializerComponent();
 
+    void setPreferredSetupActivity(in ComponentName admin, in ComponentName activity);
+
     void setUserIcon(in ComponentName admin, in Bitmap icon);
 
     void sendDeviceInitializerStatus(int statusCode, String description);
@@ -227,4 +229,9 @@
     boolean getDoNotAskCredentialsOnBoot();
 
     void notifyPendingSystemUpdate(in long updateReceivedTime);
+
+    void setPermissionPolicy(in ComponentName admin, int policy);
+    int  getPermissionPolicy(in ComponentName admin);
+    boolean setPermissionGranted(in ComponentName admin, String packageName, String permission,
+            boolean granted);
 }
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index fd65d56..72e701d 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -211,7 +211,27 @@
                 // We do not call ContentProvider#query with a modified where clause since
                 // the implementation is not guaranteed to be backed by a SQL database, hence
                 // it may not handle properly the tautology where clause we would have created.
-                return new MatrixCursor(projection, 0);
+                if (projection != null) {
+                    return new MatrixCursor(projection, 0);
+                }
+
+                // Null projection means all columns but we have no idea which they are.
+                // However, the caller may be expecting to access them my index. Hence,
+                // we have to execute the query as if allowed to get a cursor with the
+                // columns. We then use the column names to return an empty cursor.
+                Cursor cursor = ContentProvider.this.query(uri, projection, selection,
+                        selectionArgs, sortOrder, CancellationSignal.fromTransport(
+                                cancellationSignal));
+
+                // Create a projection for all columns.
+                final int columnCount = cursor.getCount();
+                String[] allColumns = new String[columnCount];
+                for (int i = 0; i < columnCount; i++) {
+                    allColumns[i] = cursor.getColumnName(i);
+                }
+
+                // Return an empty cursor for all columns.
+                return new MatrixCursor(allColumns, 0);
             }
             final String original = setCallingPackage(callingPkg);
             try {
diff --git a/core/java/android/content/pm/IPackageMoveObserver.aidl b/core/java/android/content/pm/IPackageMoveObserver.aidl
index 50ab3b5..155ed0b 100644
--- a/core/java/android/content/pm/IPackageMoveObserver.aidl
+++ b/core/java/android/content/pm/IPackageMoveObserver.aidl
@@ -22,6 +22,5 @@
  * @hide
  */
 oneway interface IPackageMoveObserver {
-    void onStarted(int moveId, String title);
-    void onStatusChanged(int moveId, int status, long estMillis);
+    void onStatusChanged(int moveId, String moveTitle, int status, long estMillis);
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e1c271d..a1ee7fc 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -209,7 +209,14 @@
      * matching.  This is a synonym for including the CATEGORY_DEFAULT in your
      * supplied Intent.
      */
-    public static final int MATCH_DEFAULT_ONLY   = 0x00010000;
+    public static final int MATCH_DEFAULT_ONLY  = 0x00010000;
+
+    /**
+     * Querying flag: if set and if the platform is doing any filtering of the results, then
+     * the filtering will not happen. This is a synonym for saying that all results should
+     * be returned.
+     */
+    public static final int MATCH_ALL = 0x00020000;
 
     /**
      * Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
@@ -2637,6 +2644,8 @@
      * {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
      * those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
      *
+     * You can also set {@link #MATCH_ALL} for preventing the filtering of the results.
+     *
      * @return A List&lt;ResolveInfo&gt; containing one entry for each matching
      *         Activity. These are ordered from best to worst match -- that
      *         is, the first item in the list is what is returned by
@@ -2658,6 +2667,8 @@
      * {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
      * those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
      *
+     * You can also set {@link #MATCH_ALL} for preventing the filtering of the results.
+     *
      * @return A List&lt;ResolveInfo&gt; containing one entry for each matching
      *         Activity. These are ordered from best to worst match -- that
      *         is, the first item in the list is what is returned by
@@ -4201,8 +4212,8 @@
 
     /** {@hide} */
     public static abstract class MoveCallback {
-        public abstract void onStarted(int moveId, String title);
-        public abstract void onStatusChanged(int moveId, int status, long estMillis);
+        public abstract void onStatusChanged(int moveId, String moveTitle, int status,
+                long estMillis);
     }
 
     /** {@hide} */
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 87a1ca9..19e821c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -603,10 +603,9 @@
     /**
      * <p>List of available high speed video size and fps range configurations
      * supported by the camera device, in the format of (width, height, fps_min, fps_max).</p>
-     * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes},
-     * this metadata will list the supported high speed video size and fps range
-     * configurations. All the sizes listed in this configuration will be a subset
-     * of the sizes reported by StreamConfigurationMap#getOutputSizes for processed
+     * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}, this metadata
+     * will list the supported high speed video size and fps range configurations. All the sizes
+     * listed in this configuration will be a subset of the sizes reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } for processed
      * non-stalling formats.</p>
      * <p>For the high speed video use case, where the application will set
      * {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the application must
@@ -1116,11 +1115,12 @@
      * into the 3 stream types as below:</p>
      * <ul>
      * <li>Processed (but stalling): any non-RAW format with a stallDurations &gt; 0.
-     * Typically JPEG format (ImageFormat#JPEG).</li>
-     * <li>Raw formats: ImageFormat#RAW_SENSOR, ImageFormat#RAW10, ImageFormat#RAW12,
-     * and ImageFormat#RAW_OPAQUE.</li>
+     *   Typically {@link android.graphics.ImageFormat#JPEG JPEG format}.</li>
+     * <li>Raw formats: {@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}, {@link android.graphics.ImageFormat#RAW10 RAW10}, or {@link android.graphics.ImageFormat#RAW12 RAW12}.</li>
      * <li>Processed (but not-stalling): any non-RAW format without a stall duration.
-     * Typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12.</li>
+     *   Typically {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888},
+     *   {@link android.graphics.ImageFormat#NV21 NV21}, or
+     *   {@link android.graphics.ImageFormat#YV12 YV12}.</li>
      * </ul>
      * <p><b>Range of valid values:</b><br></p>
      * <p>For processed (and stalling) format streams, &gt;= 1.</p>
@@ -1148,10 +1148,9 @@
      * be any <code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
      * <p>In particular, a <code>RAW</code> format is typically one of:</p>
      * <ul>
-     * <li>ImageFormat#RAW_SENSOR</li>
-     * <li>ImageFormat#RAW10</li>
-     * <li>ImageFormat#RAW12</li>
-     * <li>Opaque <code>RAW</code></li>
+     * <li>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</li>
+     * <li>{@link android.graphics.ImageFormat#RAW10 RAW10}</li>
+     * <li>{@link android.graphics.ImageFormat#RAW12 RAW12}</li>
      * </ul>
      * <p>LEGACY mode devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> LEGACY)
      * never support raw streams.</p>
@@ -1180,13 +1179,13 @@
      * <p>Processed (but not-stalling) is defined as any non-RAW format without a stall duration.
      * Typically:</p>
      * <ul>
-     * <li>ImageFormat#YUV_420_888</li>
-     * <li>ImageFormat#NV21</li>
-     * <li>ImageFormat#YV12</li>
-     * <li>Implementation-defined formats, i.e. StreamConfiguration#isOutputSupportedFor(Class)</li>
+     * <li>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</li>
+     * <li>{@link android.graphics.ImageFormat#NV21 NV21}</li>
+     * <li>{@link android.graphics.ImageFormat#YV12 YV12}</li>
+     * <li>Implementation-defined formats, i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#isOutputSupportedFor(Class) }</li>
      * </ul>
-     * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
-     * a processed format -- it will return 0 for a non-stalling stream.</p>
+     * <p>For full guarantees, query {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } with a
+     * processed format -- it will return 0 for a non-stalling stream.</p>
      * <p>LEGACY devices will support at least 2 processing/non-stalling streams.</p>
      * <p><b>Range of valid values:</b><br></p>
      * <p>&gt;= 3
@@ -1212,10 +1211,11 @@
      * the camera device. Using more streams simultaneously may require more hardware and
      * CPU resources that will consume more power. The image format for this kind of an output stream can
      * be any non-<code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
-     * <p>A processed and stalling format is defined as any non-RAW format with a stallDurations &gt; 0.
-     * Typically only the <code>JPEG</code> format (ImageFormat#JPEG) is a stalling format.</p>
-     * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
-     * a processed format -- it will return a non-0 value for a stalling stream.</p>
+     * <p>A processed and stalling format is defined as any non-RAW format with a stallDurations
+     * &gt; 0.  Typically only the {@link android.graphics.ImageFormat#JPEG JPEG format} is a
+     * stalling format.</p>
+     * <p>For full guarantees, query {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } with a
+     * processed format -- it will return a non-0 value for a stalling stream.</p>
      * <p>LEGACY devices will support up to 1 processing/stalling stream.</p>
      * <p><b>Range of valid values:</b><br></p>
      * <p>&gt;= 1</p>
@@ -1232,10 +1232,9 @@
      * <p>The maximum numbers of any type of input streams
      * that can be configured and used simultaneously by a camera device.</p>
      * <p>When set to 0, it means no input stream is supported.</p>
-     * <p>The image format for a input stream can be any supported
-     * format returned by StreamConfigurationMap#getInputFormats. When using an
-     * input stream, there must be at least one output stream
-     * configured to to receive the reprocessed images.</p>
+     * <p>The image format for a input stream can be any supported format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }. When using an
+     * input stream, there must be at least one output stream configured to to receive the
+     * reprocessed images.</p>
      * <p>When an input stream and some output streams are used in a reprocessing request,
      * only the input buffer will be used to produce these output stream buffers, and a
      * new sensor image will not be captured.</p>
@@ -1352,7 +1351,7 @@
 
     /**
      * <p>A list of all keys that the camera device has available
-     * to use with CaptureRequest.</p>
+     * to use with {@link android.hardware.camera2.CaptureRequest }.</p>
      * <p>Attempting to set a key into a CaptureRequest that is not
      * listed here will result in an invalid request and will be rejected
      * by the camera device.</p>
@@ -1370,7 +1369,7 @@
 
     /**
      * <p>A list of all keys that the camera device has available
-     * to use with CaptureResult.</p>
+     * to use with {@link android.hardware.camera2.CaptureResult }.</p>
      * <p>Attempting to get a key from a CaptureResult that is not
      * listed here will always return a <code>null</code> value. Getting a key from
      * a CaptureResult that is listed here will generally never return a <code>null</code>
@@ -1396,7 +1395,7 @@
 
     /**
      * <p>A list of all keys that the camera device has available
-     * to use with CameraCharacteristics.</p>
+     * to use with {@link android.hardware.camera2.CameraCharacteristics }.</p>
      * <p>This entry follows the same rules as
      * android.request.availableResultKeys (except that it applies for
      * CameraCharacteristics instead of CaptureResult). See above for more
@@ -1535,34 +1534,31 @@
      * </thead>
      * <tbody>
      * <tr>
-     * <td align="left">PRIVATE (ImageFormat#PRIVATE)</td>
-     * <td align="left">JPEG</td>
+     * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
+     * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
      * <td align="left">OPAQUE_REPROCESSING</td>
      * </tr>
      * <tr>
-     * <td align="left">PRIVATE</td>
-     * <td align="left">YUV_420_888</td>
+     * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
+     * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
      * <td align="left">OPAQUE_REPROCESSING</td>
      * </tr>
      * <tr>
-     * <td align="left">YUV_420_888</td>
-     * <td align="left">JPEG</td>
+     * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+     * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
      * <td align="left">YUV_REPROCESSING</td>
      * </tr>
      * <tr>
-     * <td align="left">YUV_420_888</td>
-     * <td align="left">YUV_420_888</td>
+     * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+     * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
      * <td align="left">YUV_REPROCESSING</td>
      * </tr>
      * </tbody>
      * </table>
-     * <p>PRIVATE refers to a device-internal format that is not directly application-visible.
-     * A PRIVATE input surface can be acquired by
-     * ImageReader.newOpaqueInstance(width, height, maxImages).
-     * For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format
-     * as either input or output will never hurt maximum frame rate (i.e.
-     * StreamConfigurationMap#getOutputStallDuration(format, size) is always 0),
-     * where format is ImageFormat#PRIVATE.</p>
+     * <p>PRIVATE refers to a device-internal format that is not directly application-visible.  A
+     * PRIVATE input surface can be acquired by {@link android.media.ImageReader#newOpaqueInstance }.</p>
+     * <p>For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format as either input
+     * or output will never hurt maximum frame rate (i.e.  {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration getOutputStallDuration(ImageFormat.PRIVATE, size)} is always 0),</p>
      * <p>Attempting to configure an input stream with output streams not
      * listed as available in this map is not valid.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
@@ -1680,7 +1676,7 @@
      * android.scaler.availableStallDurations for more details about
      * calculating the max frame rate.</p>
      * <p>(Keep in sync with
-     * StreamConfigurationMap#getOutputMinFrameDuration)</p>
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration })</p>
      * <p><b>Units</b>: (format, width, height, ns) x n</p>
      * <p>This key is available on all devices.</p>
      *
@@ -1692,7 +1688,7 @@
 
     /**
      * <p>This lists the maximum stall duration for each
-     * format/size combination.</p>
+     * output format/size combination.</p>
      * <p>A stall duration is how much extra time would get added
      * to the normal minimum frame duration for a repeating request
      * that has streams with non-zero stall.</p>
@@ -1734,12 +1730,13 @@
      * ignored).</p>
      * <p>The following formats may always have a stall duration:</p>
      * <ul>
-     * <li>ImageFormat#JPEG</li>
-     * <li>ImageFormat#RAW_SENSOR</li>
+     * <li>{@link android.graphics.ImageFormat#JPEG }</li>
+     * <li>{@link android.graphics.ImageFormat#RAW_SENSOR }</li>
      * </ul>
      * <p>The following formats will never have a stall duration:</p>
      * <ul>
-     * <li>ImageFormat#YUV_420_888</li>
+     * <li>{@link android.graphics.ImageFormat#YUV_420_888 }</li>
+     * <li>{@link android.graphics.ImageFormat#RAW10 }</li>
      * </ul>
      * <p>All other formats may or may not have an allowed stall duration on
      * a per-capability basis; refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
@@ -1747,7 +1744,7 @@
      * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} for more information about
      * calculating the max frame rate (absent stalls).</p>
      * <p>(Keep up to date with
-     * StreamConfigurationMap#getOutputStallDuration(int, Size) )</p>
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } )</p>
      * <p><b>Units</b>: (format, width, height, ns) x n</p>
      * <p>This key is available on all devices.</p>
      *
@@ -1786,57 +1783,57 @@
      * </thead>
      * <tbody>
      * <tr>
-     * <td align="center">JPEG</td>
+     * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
      * <td align="center">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</td>
      * <td align="center">Any</td>
      * <td align="center"></td>
      * </tr>
      * <tr>
-     * <td align="center">JPEG</td>
+     * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
      * <td align="center">1920x1080 (1080p)</td>
      * <td align="center">Any</td>
      * <td align="center">if 1080p &lt;= activeArraySize</td>
      * </tr>
      * <tr>
-     * <td align="center">JPEG</td>
+     * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
      * <td align="center">1280x720 (720)</td>
      * <td align="center">Any</td>
      * <td align="center">if 720p &lt;= activeArraySize</td>
      * </tr>
      * <tr>
-     * <td align="center">JPEG</td>
+     * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
      * <td align="center">640x480 (480p)</td>
      * <td align="center">Any</td>
      * <td align="center">if 480p &lt;= activeArraySize</td>
      * </tr>
      * <tr>
-     * <td align="center">JPEG</td>
+     * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
      * <td align="center">320x240 (240p)</td>
      * <td align="center">Any</td>
      * <td align="center">if 240p &lt;= activeArraySize</td>
      * </tr>
      * <tr>
-     * <td align="center">YUV_420_888</td>
+     * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
      * <td align="center">all output sizes available for JPEG</td>
      * <td align="center">FULL</td>
      * <td align="center"></td>
      * </tr>
      * <tr>
-     * <td align="center">YUV_420_888</td>
+     * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
      * <td align="center">all output sizes available for JPEG, up to the maximum video size</td>
      * <td align="center">LIMITED</td>
      * <td align="center"></td>
      * </tr>
      * <tr>
-     * <td align="center">IMPLEMENTATION_DEFINED</td>
+     * <td align="center">{@link android.graphics.ImageFormat#PRIVATE }</td>
      * <td align="center">same as YUV_420_888</td>
      * <td align="center">Any</td>
      * <td align="center"></td>
      * </tr>
      * </tbody>
      * </table>
-     * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} for additional
-     * mandatory stream configurations on a per-capability basis.</p>
+     * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} and {@link android.hardware.camera2.CameraDevice#createCaptureSession } for additional mandatory
+     * stream configurations on a per-capability basis.</p>
      * <p>This key is available on all devices.</p>
      *
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
@@ -1973,8 +1970,8 @@
      * <p>Attempting to use frame durations beyond the maximum will result in the frame
      * duration being clipped to the maximum. See that control for a full definition of frame
      * durations.</p>
-     * <p>Refer to StreamConfigurationMap#getOutputMinFrameDuration(int,Size) for the minimum
-     * frame duration values.</p>
+     * <p>Refer to {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+     * for the minimum frame duration values.</p>
      * <p><b>Units</b>: Nanoseconds</p>
      * <p><b>Range of valid values:</b><br>
      * For FULL capability devices
@@ -2634,6 +2631,41 @@
             new Key<Integer>("android.sync.maxLatency", int.class);
 
     /**
+     * <p>The maximal camera capture pipeline stall (in unit of frame count) introduced by a
+     * reprocess capture request.</p>
+     * <p>The key describes the maximal interference that one reprocess (input) request
+     * can introduce to the camera simultaneous streaming of regular (output) capture
+     * requests, including repeating requests.</p>
+     * <p>When a reprocessing capture request is submitted while a camera output repeating request
+     * (e.g. preview) is being served by the camera device, it may preempt the camera capture
+     * pipeline for at least one frame duration so that the camera device is unable to process
+     * the following capture request in time for the next sensor start of exposure boundary.
+     * When this happens, the application may observe a capture time gap (longer than one frame
+     * duration) between adjacent capture output frames, which usually exhibits as preview
+     * glitch if the repeating request output targets include a preview surface. This key gives
+     * the worst-case number of frame stall introduced by one reprocess request with any kind of
+     * formats/sizes combination.</p>
+     * <p>If this key reports 0, it means a reprocess request doesn't introduce any glitch to the
+     * ongoing camera repeating request outputs, as if this reprocess request is never issued.</p>
+     * <p>This key is supported if the camera device supports OPAQUE or YUV reprocessing (
+     * i.e. {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains OPAQUE_REPROCESSING or
+     * YUV_REPROCESSING).</p>
+     * <p><b>Units</b>: Number of frames.</p>
+     * <p><b>Range of valid values:</b><br>
+     * &lt;= 4</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * <p><b>Limited capability</b> -
+     * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+     *
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    @PublicKey
+    public static final Key<Integer> REPROCESS_MAX_CAPTURE_STALL =
+            new Key<Integer>("android.reprocess.maxCaptureStall", int.class);
+
+    /**
      * <p>The available depth dataspace stream
      * configurations that this camera device supports
      * (i.e. format, width, height, output/input stream).</p>
@@ -2672,8 +2704,7 @@
      * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
      * android.scaler.availableStallDurations for more details about
      * calculating the max frame rate.</p>
-     * <p>(Keep in sync with
-     * StreamConfigurationMap#getOutputMinFrameDuration)</p>
+     * <p>(Keep in sync with {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration })</p>
      * <p><b>Units</b>: (format, width, height, ns) x n</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
@@ -2689,7 +2720,7 @@
 
     /**
      * <p>This lists the maximum stall duration for each
-     * format/size combination for depth streams.</p>
+     * output format/size combination for depth streams.</p>
      * <p>A stall duration is how much extra time would get added
      * to the normal minimum frame duration for a repeating request
      * that has streams with non-zero stall.</p>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 51b326b..f6791a4 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -54,6 +54,7 @@
      * means that high frame rate is given priority over the highest-quality
      * post-processing. These requests would normally be used with the
      * {@link CameraCaptureSession#setRepeatingRequest} method.
+     * This template is guaranteed to be supported on all camera devices.
      *
      * @see #createCaptureRequest
      */
@@ -63,6 +64,7 @@
      * Create a request suitable for still image capture. Specifically, this
      * means prioritizing image quality over frame rate. These requests would
      * commonly be used with the {@link CameraCaptureSession#capture} method.
+     * This template is guaranteed to be supported on all camera devices.
      *
      * @see #createCaptureRequest
      */
@@ -73,6 +75,7 @@
      * that a stable frame rate is used, and post-processing is set for
      * recording quality. These requests would commonly be used with the
      * {@link CameraCaptureSession#setRepeatingRequest} method.
+     * This template is guaranteed to be supported on all camera devices.
      *
      * @see #createCaptureRequest
      */
@@ -84,6 +87,9 @@
      * disrupting the ongoing recording. These requests would commonly be used
      * with the {@link CameraCaptureSession#capture} method while a request based on
      * {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
+     * This template is guaranteed to be supported on all camera devices except
+     * legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+     * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY})
      *
      * @see #createCaptureRequest
      */
@@ -93,6 +99,11 @@
      * Create a request suitable for zero shutter lag still capture. This means
      * means maximizing image quality without compromising preview frame rate.
      * AE/AWB/AF should be on auto mode.
+     * This template is guaranteed to be supported on camera devices that support the
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING}
+     * capability or the
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}
+     * capability.
      *
      * @see #createCaptureRequest
      */
@@ -105,6 +116,9 @@
      * quality. The manual capture parameters (exposure, sensitivity, and so on)
      * are set to reasonable defaults, but should be overriden by the
      * application depending on the intended use case.
+     * This template is guaranteed to be supported on camera devices that support the
+     * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}
+     * capability.
      *
      * @see #createCaptureRequest
      */
@@ -473,12 +487,14 @@
      * settings as desired, instead.</p>
      *
      * @param templateType An enumeration selecting the use case for this
-     * request; one of the CameraDevice.TEMPLATE_ values.
+     * request; one of the CameraDevice.TEMPLATE_ values. Not all template
+     * types are supported on every device. See the documentation for each
+     * template type for details.
      * @return a builder for a capture request, initialized with default
      * settings for that template, and no output streams
      *
-     * @throws IllegalArgumentException if the templateType is not in the list
-     * of supported templates.
+     * @throws IllegalArgumentException if the templateType is not supported by
+     * this device.
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
      * @throws IllegalStateException if the camera device has been closed
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e3f1d73..ca9439b 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -461,22 +461,21 @@
      * <p>The camera device supports the Zero Shutter Lag reprocessing use case.</p>
      * <ul>
      * <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
-     * <li>ImageFormat#PRIVATE is supported as an output/input format, that is,
-     *   ImageFormat#PRIVATE is included in the lists of formats returned by
-     *   StreamConfigurationMap#getInputFormats and
-     *   StreamConfigurationMap#getOutputFormats.</li>
-     * <li>StreamConfigurationMap#getValidOutputFormatsForInput returns non empty int[] for
-     *   each supported input format returned by StreamConfigurationMap#getInputFormats.</li>
-     * <li>Each size returned by StreamConfigurationMap#getInputSizes(ImageFormat#PRIVATE)
-     *   is also included in StreamConfigurationMap#getOutputSizes(ImageFormat#PRIVATE)</li>
-     * <li>Using ImageFormat#PRIVATE does not cause a frame rate drop
-     *   relative to the sensor's maximum capture rate (at that
-     *   resolution).</li>
-     * <li>ImageFormat#PRIVATE will be reprocessable into both YUV_420_888
-     *   and JPEG formats.</li>
+     * <li>{@link android.graphics.ImageFormat#PRIVATE } is supported as an output/input format,
+     *   that is, {@link android.graphics.ImageFormat#PRIVATE } is included in the lists of
+     *   formats returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
+     * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+     *   returns non empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+     * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(ImageFormat.PRIVATE)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(ImageFormat.PRIVATE)}</li>
+     * <li>Using {@link android.graphics.ImageFormat#PRIVATE } does not cause a frame rate drop
+     *   relative to the sensor's maximum capture rate (at that resolution).</li>
+     * <li>{@link android.graphics.ImageFormat#PRIVATE } will be reprocessable into both
+     *   {@link android.graphics.ImageFormat#YUV_420_888 } and
+     *   {@link android.graphics.ImageFormat#JPEG } formats.</li>
      * <li>The maximum available resolution for OPAQUE streams
      *   (both input/output) will match the maximum available
      *   resolution of JPEG streams.</li>
+     * <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
      * <li>Only below controls are effective for reprocessing requests and
      *   will be present in capture results, other controls in reprocess
      *   requests will be ignored by the camera device.<ul>
@@ -489,6 +488,7 @@
      *
      * @see CaptureRequest#EDGE_MODE
      * @see CaptureRequest#NOISE_REDUCTION_MODE
+     * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL
      * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      */
@@ -569,25 +569,25 @@
      * following:</p>
      * <ul>
      * <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
-     * <li>YUV_420_888 is supported as an output/input format, that is,
+     * <li>{@link android.graphics.ImageFormat#YUV_420_888 } is supported as an output/input format, that is,
      *   YUV_420_888 is included in the lists of formats returned by
-     *   StreamConfigurationMap#getInputFormats and
-     *   StreamConfigurationMap#getOutputFormats.</li>
-     * <li>StreamConfigurationMap#getValidOutputFormatsForInput returns non empty int[] for
-     *   each supported input format returned by StreamConfigurationMap#getInputFormats.</li>
-     * <li>Each size returned by StreamConfigurationMap#getInputSizes(YUV_420_888)
-     *   is also included in StreamConfigurationMap#getOutputSizes(YUV_420_888)</li>
-     * <li>Using YUV_420_888 does not cause a frame rate drop
+     *   {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and
+     *   {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
+     * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+     *   returns non-empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+     * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(YUV_420_888)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(YUV_420_888)}</li>
+     * <li>Using {@link android.graphics.ImageFormat#YUV_420_888 } does not cause a frame rate drop
      *   relative to the sensor's maximum capture rate (at that resolution).</li>
-     * <li>YUV_420_888 will be reprocessable into both YUV_420_888
-     *   and JPEG formats.</li>
-     * <li>The maximum available resolution for YUV_420_888 streams
-     *   (both input/output) will match the maximum available
-     *   resolution of JPEG streams.</li>
-     * <li>Only the below controls are effective for reprocessing requests and will be
-     *   present in capture results. The reprocess requests are from the original capture
-     *   results that are assocaited with the intermidate YUV_420_888 output buffers.
-     *   All other controls in the reprocess requests will be ignored by the camera device.<ul>
+     * <li>{@link android.graphics.ImageFormat#YUV_420_888 } will be reprocessable into both
+     *   {@link android.graphics.ImageFormat#YUV_420_888 } and {@link android.graphics.ImageFormat#JPEG } formats.</li>
+     * <li>The maximum available resolution for {@link android.graphics.ImageFormat#YUV_420_888 } streams (both input/output) will match the
+     *   maximum available resolution of {@link android.graphics.ImageFormat#JPEG } streams.</li>
+     * <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
+     * <li>Only the below controls are effective for reprocessing requests and will be present
+     *   in capture results. The reprocess requests are from the original capture results that
+     *   are associated with the intermediate {@link android.graphics.ImageFormat#YUV_420_888 }
+     *   output buffers.  All other controls in the reprocess requests will be ignored by the
+     *   camera device.<ul>
      * <li>android.jpeg.*</li>
      * <li>{@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}</li>
      * <li>{@link CaptureRequest#EDGE_MODE android.edge.mode}</li>
@@ -599,6 +599,7 @@
      * @see CaptureRequest#EDGE_MODE
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      * @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
+     * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL
      * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      */
@@ -608,11 +609,13 @@
      * <p>The camera device can produce depth measurements from its field of view.</p>
      * <p>This capability requires the camera device to support the following:</p>
      * <ul>
-     * <li>DEPTH16 is supported as an output format.</li>
-     * <li>DEPTH_POINT_CLOUD is optionally supported as an output format.</li>
-     * <li>This camera device, and all camera devices with the same android.lens.info.facing,
-     *   will list the following calibration entries in both CameraCharacteristics and
-     *   CaptureResults:<ul>
+     * <li>{@link android.graphics.ImageFormat#DEPTH16 } is supported as an output format.</li>
+     * <li>{@link android.graphics.ImageFormat#DEPTH_POINT_CLOUD } is optionally supported as an
+     *   output format.</li>
+     * <li>This camera device, and all camera devices with the same {@link CameraCharacteristics#LENS_FACING android.lens.facing},
+     *   will list the following calibration entries in both
+     *   {@link android.hardware.camera2.CameraCharacteristics } and
+     *   {@link android.hardware.camera2.CaptureResult }:<ul>
      * <li>{@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}</li>
      * <li>{@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation}</li>
      * <li>android.lens.intrinsicCalibration</li>
@@ -627,13 +630,14 @@
      * <p>Generally, depth output operates at a slower frame rate than standard color capture,
      * so the DEPTH16 and DEPTH_POINT_CLOUD formats will commonly have a stall duration that
      * should be accounted for (see
-     * android.hardware.camera2.StreamConfigurationMap#getOutputStallDuration).  On a device
-     * that supports both depth and color-based output, to enable smooth preview, using a
-     * repeating burst is recommended, where a depth-output target is only included once
-     * every N frames, where N is the ratio between preview output rate and depth output
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }).
+     * On a device that supports both depth and color-based output, to enable smooth preview,
+     * using a repeating burst is recommended, where a depth-output target is only included
+     * once every N frames, where N is the ratio between preview output rate and depth output
      * rate, including depth stall time.</p>
      *
      * @see CameraCharacteristics#DEPTH_DEPTH_IS_EXCLUSIVE
+     * @see CameraCharacteristics#LENS_FACING
      * @see CameraCharacteristics#LENS_POSE_ROTATION
      * @see CameraCharacteristics#LENS_POSE_TRANSLATION
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
@@ -707,7 +711,7 @@
 
     /**
      * <p>Timestamps from {@link CaptureResult#SENSOR_TIMESTAMP android.sensor.timestamp} are in the same timebase as
-     * android.os.SystemClock#elapsedRealtimeNanos(),
+     * {@link android.os.SystemClock#elapsedRealtimeNanos },
      * and they can be compared to other timestamps using that base.</p>
      *
      * @see CaptureResult#SENSOR_TIMESTAMP
@@ -866,7 +870,7 @@
     /**
      * <p>Every frame has the requests immediately applied.</p>
      * <p>Furthermore for all results,
-     * <code>android.sync.frameNumber == CaptureResult#getFrameNumber()</code></p>
+     * <code>android.sync.frameNumber == {@link android.hardware.camera2.CaptureResult#getFrameNumber }</code></p>
      * <p>Changing controls over multiple requests one after another will
      * produce results that have those controls applied atomically
      * each frame.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 19d17b1..ab6ce91 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1275,8 +1275,9 @@
      * <p>This control (except for MANUAL) is only effective if
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
      * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains MANUAL_SENSOR. Other intent values are always supported.</p>
+     * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+     * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
+     * always supported.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2039,8 +2040,8 @@
      * cannot process more than 1 capture at a time.</li>
      * </ul>
      * <p>The necessary information for the application, given the model above,
-     * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field
-     * using StreamConfigurationMap#getOutputMinFrameDuration(int, Size).
+     * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field using
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.
      * These are used to determine the maximum frame rate / minimum frame
      * duration that is possible for a given stream configuration.</p>
      * <p>Specifically, the application can use the following rules to
@@ -2049,21 +2050,19 @@
      * <ol>
      * <li>Let the set of currently configured input/output streams
      * be called <code>S</code>.</li>
-     * <li>Find the minimum frame durations for each stream in <code>S</code>, by
-     * looking it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using
-     * StreamConfigurationMap#getOutputMinFrameDuration(int, Size) (with
-     * its respective size/format). Let this set of frame durations be called
-     * <code>F</code>.</li>
+     * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
+     * it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+     * (with its respective size/format). Let this set of frame durations be
+     * called <code>F</code>.</li>
      * <li>For any given request <code>R</code>, the minimum frame duration allowed
      * for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
      * used in <code>R</code> be called <code>S_r</code>.</li>
      * </ol>
-     * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
-     * StreamConfigurationMap#getOutputStallDuration(int,Size) using its
-     * respective size/format), then the frame duration in
-     * <code>F</code> determines the steady state frame rate that the application will
-     * get if it uses <code>R</code> as a repeating request. Let this special kind
-     * of request be called <code>Rsimple</code>.</p>
+     * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }
+     * using its respective size/format), then the frame duration in <code>F</code>
+     * determines the steady state frame rate that the application will get
+     * if it uses <code>R</code> as a repeating request. Let this special kind of
+     * request be called <code>Rsimple</code>.</p>
      * <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
      * by a single capture of a new request <code>Rstall</code> (which has at least
      * one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
@@ -2071,7 +2070,7 @@
      * if all buffers from the previous <code>Rstall</code> have already been
      * delivered.</p>
      * <p>For more details about stalling, see
-     * StreamConfigurationMap#getOutputStallDuration(int,Size).</p>
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
      * OFF; otherwise the auto-exposure algorithm will override this value.</p>
      * <p><b>Units</b>: Nanoseconds</p>
@@ -2647,8 +2646,12 @@
      * <p><b>Range of valid values:</b><br>
      * &gt;= 1.0</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * <p><b>Limited capability</b> -
+     * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
      *
      * @see CaptureRequest#EDGE_MODE
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      */
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ef5d75c..3dc8970 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1698,8 +1698,9 @@
      * <p>This control (except for MANUAL) is only effective if
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
      * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains MANUAL_SENSOR. Other intent values are always supported.</p>
+     * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+     * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
+     * always supported.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2885,8 +2886,8 @@
      * cannot process more than 1 capture at a time.</li>
      * </ul>
      * <p>The necessary information for the application, given the model above,
-     * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field
-     * using StreamConfigurationMap#getOutputMinFrameDuration(int, Size).
+     * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field using
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.
      * These are used to determine the maximum frame rate / minimum frame
      * duration that is possible for a given stream configuration.</p>
      * <p>Specifically, the application can use the following rules to
@@ -2895,21 +2896,19 @@
      * <ol>
      * <li>Let the set of currently configured input/output streams
      * be called <code>S</code>.</li>
-     * <li>Find the minimum frame durations for each stream in <code>S</code>, by
-     * looking it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using
-     * StreamConfigurationMap#getOutputMinFrameDuration(int, Size) (with
-     * its respective size/format). Let this set of frame durations be called
-     * <code>F</code>.</li>
+     * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
+     * it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+     * (with its respective size/format). Let this set of frame durations be
+     * called <code>F</code>.</li>
      * <li>For any given request <code>R</code>, the minimum frame duration allowed
      * for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
      * used in <code>R</code> be called <code>S_r</code>.</li>
      * </ol>
-     * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
-     * StreamConfigurationMap#getOutputStallDuration(int,Size) using its
-     * respective size/format), then the frame duration in
-     * <code>F</code> determines the steady state frame rate that the application will
-     * get if it uses <code>R</code> as a repeating request. Let this special kind
-     * of request be called <code>Rsimple</code>.</p>
+     * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }
+     * using its respective size/format), then the frame duration in <code>F</code>
+     * determines the steady state frame rate that the application will get
+     * if it uses <code>R</code> as a repeating request. Let this special kind of
+     * request be called <code>Rsimple</code>.</p>
      * <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
      * by a single capture of a new request <code>Rstall</code> (which has at least
      * one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
@@ -2917,7 +2916,7 @@
      * if all buffers from the previous <code>Rstall</code> have already been
      * delivered.</p>
      * <p>For more details about stalling, see
-     * StreamConfigurationMap#getOutputStallDuration(int,Size).</p>
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
      * OFF; otherwise the auto-exposure algorithm will override this value.</p>
      * <p><b>Units</b>: Nanoseconds</p>
@@ -2979,11 +2978,10 @@
      * and are monotonically increasing. They can be compared with the
      * timestamps for other captures from the same camera device, but are
      * not guaranteed to be comparable to any other time source.</p>
-     * <p>When {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE android.sensor.info.timestampSource} <code>==</code> REALTIME,
-     * the timestamps measure time in the same timebase as
-     * android.os.SystemClock#elapsedRealtimeNanos(), and they can be
-     * compared to other timestamps from other subsystems that are using
-     * that base.</p>
+     * <p>When {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE android.sensor.info.timestampSource} <code>==</code> REALTIME, the
+     * timestamps measure time in the same timebase as {@link android.os.SystemClock#elapsedRealtimeNanos }, and they can
+     * be compared to other timestamps from other subsystems that
+     * are using that base.</p>
      * <p><b>Units</b>: Nanoseconds</p>
      * <p><b>Range of valid values:</b><br>
      * &gt; 0</p>
@@ -3141,7 +3139,7 @@
      * <p><b>Units</b>: Nanoseconds</p>
      * <p><b>Range of valid values:</b><br>
      * &gt;= 0 and &lt;
-     * StreamConfigurationMap#getOutputMinFrameDuration(int, Size).</p>
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -3966,8 +3964,12 @@
      * <p><b>Range of valid values:</b><br>
      * &gt;= 1.0</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * <p><b>Limited capability</b> -
+     * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
      *
      * @see CaptureRequest#EDGE_MODE
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      */
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index adab9be..02793f1 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -182,6 +182,10 @@
         // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter).
         public float screenAutoBrightnessAdjustment;
 
+        // Set to true if screenBrightness and screenAutoBrightnessAdjustment were both
+        // set by the user as opposed to being programmatically controlled by apps.
+        public boolean brightnessSetByUser;
+
         // If true, enables automatic brightness control.
         public boolean useAutoBrightness;
 
@@ -229,6 +233,7 @@
             useProximitySensor = other.useProximitySensor;
             screenBrightness = other.screenBrightness;
             screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
+            brightnessSetByUser = other.brightnessSetByUser;
             useAutoBrightness = other.useAutoBrightness;
             blockScreenOn = other.blockScreenOn;
             lowPowerMode = other.lowPowerMode;
@@ -249,6 +254,7 @@
                     && useProximitySensor == other.useProximitySensor
                     && screenBrightness == other.screenBrightness
                     && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
+                    && brightnessSetByUser == other.brightnessSetByUser
                     && useAutoBrightness == other.useAutoBrightness
                     && blockScreenOn == other.blockScreenOn
                     && lowPowerMode == other.lowPowerMode
@@ -268,6 +274,7 @@
                     + ", useProximitySensor=" + useProximitySensor
                     + ", screenBrightness=" + screenBrightness
                     + ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
+                    + ", brightnessSetByUser=" + brightnessSetByUser
                     + ", useAutoBrightness=" + useAutoBrightness
                     + ", blockScreenOn=" + blockScreenOn
                     + ", lowPowerMode=" + lowPowerMode
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 16e0bf7..fcde3f4 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -942,6 +942,24 @@
             }
 
             @Override
+            public VolumeRecord[] getVolumeRecords(int _flags) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                VolumeRecord[] _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(_flags);
+                    mRemote.transact(Stub.TRANSACTION_getVolumeRecords, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.createTypedArray(VolumeRecord.CREATOR);
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            @Override
             public void mount(String volId) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -1033,12 +1051,12 @@
             }
 
             @Override
-            public void setVolumeNickname(String volId, String nickname) throws RemoteException {
+            public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volId);
+                    _data.writeString(fsUuid);
                     _data.writeString(nickname);
                     mRemote.transact(Stub.TRANSACTION_setVolumeNickname, _data, _reply, 0);
                     _reply.readException();
@@ -1049,12 +1067,12 @@
             }
 
             @Override
-            public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException {
+            public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeString(volId);
+                    _data.writeString(fsUuid);
                     _data.writeInt(flags);
                     _data.writeInt(mask);
                     mRemote.transact(Stub.TRANSACTION_setVolumeUserFlags, _data, _reply, 0);
@@ -1066,6 +1084,21 @@
             }
 
             @Override
+            public void forgetVolume(String fsUuid) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(fsUuid);
+                    mRemote.transact(Stub.TRANSACTION_forgetVolume, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
             public String getPrimaryStorageUuid() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -1192,20 +1225,22 @@
 
         static final int TRANSACTION_getDisks = IBinder.FIRST_CALL_TRANSACTION + 44;
         static final int TRANSACTION_getVolumes = IBinder.FIRST_CALL_TRANSACTION + 45;
+        static final int TRANSACTION_getVolumeRecords = IBinder.FIRST_CALL_TRANSACTION + 46;
 
-        static final int TRANSACTION_mount = IBinder.FIRST_CALL_TRANSACTION + 46;
-        static final int TRANSACTION_unmount = IBinder.FIRST_CALL_TRANSACTION + 47;
-        static final int TRANSACTION_format = IBinder.FIRST_CALL_TRANSACTION + 48;
+        static final int TRANSACTION_mount = IBinder.FIRST_CALL_TRANSACTION + 47;
+        static final int TRANSACTION_unmount = IBinder.FIRST_CALL_TRANSACTION + 48;
+        static final int TRANSACTION_format = IBinder.FIRST_CALL_TRANSACTION + 49;
 
-        static final int TRANSACTION_partitionPublic = IBinder.FIRST_CALL_TRANSACTION + 49;
-        static final int TRANSACTION_partitionPrivate = IBinder.FIRST_CALL_TRANSACTION + 50;
-        static final int TRANSACTION_partitionMixed = IBinder.FIRST_CALL_TRANSACTION + 51;
+        static final int TRANSACTION_partitionPublic = IBinder.FIRST_CALL_TRANSACTION + 50;
+        static final int TRANSACTION_partitionPrivate = IBinder.FIRST_CALL_TRANSACTION + 51;
+        static final int TRANSACTION_partitionMixed = IBinder.FIRST_CALL_TRANSACTION + 52;
 
-        static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 52;
-        static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 53;
+        static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 53;
+        static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 54;
+        static final int TRANSACTION_forgetVolume = IBinder.FIRST_CALL_TRANSACTION + 55;
 
-        static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 54;
-        static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 55;
+        static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 56;
+        static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57;
 
         /**
          * Cast an IBinder object into an IMountService interface, generating a
@@ -1647,6 +1682,14 @@
                     reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                     return true;
                 }
+                case TRANSACTION_getVolumeRecords: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int _flags = data.readInt();
+                    VolumeRecord[] volumes = getVolumeRecords(_flags);
+                    reply.writeNoException();
+                    reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+                    return true;
+                }
                 case TRANSACTION_mount: {
                     data.enforceInterface(DESCRIPTOR);
                     String volId = data.readString();
@@ -1707,6 +1750,13 @@
                     reply.writeNoException();
                     return true;
                 }
+                case TRANSACTION_forgetVolume: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String fsUuid = data.readString();
+                    forgetVolume(fsUuid);
+                    reply.writeNoException();
+                    return true;
+                }
                 case TRANSACTION_getPrimaryStorageUuid: {
                     data.enforceInterface(DESCRIPTOR);
                     String volumeUuid = getPrimaryStorageUuid();
@@ -2012,6 +2062,7 @@
 
     public DiskInfo[] getDisks() throws RemoteException;
     public VolumeInfo[] getVolumes(int flags) throws RemoteException;
+    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException;
 
     public void mount(String volId) throws RemoteException;
     public void unmount(String volId) throws RemoteException;
@@ -2021,8 +2072,9 @@
     public void partitionPrivate(String diskId) throws RemoteException;
     public void partitionMixed(String diskId, int ratio) throws RemoteException;
 
-    public void setVolumeNickname(String volId, String nickname) throws RemoteException;
-    public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException;
+    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException;
+    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException;
+    public void forgetVolume(String fsUuid) throws RemoteException;
 
     public String getPrimaryStorageUuid() throws RemoteException;
     public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java
index fcb4779..2d13e49 100644
--- a/core/java/android/os/storage/IMountServiceListener.java
+++ b/core/java/android/os/storage/IMountServiceListener.java
@@ -93,8 +93,8 @@
                 }
                 case TRANSACTION_onVolumeMetadataChanged: {
                     data.enforceInterface(DESCRIPTOR);
-                    final VolumeInfo vol = (VolumeInfo) data.readParcelable(null);
-                    onVolumeMetadataChanged(vol);
+                    final String fsUuid = data.readString();
+                    onVolumeMetadataChanged(fsUuid);
                     reply.writeNoException();
                     return true;
                 }
@@ -192,12 +192,12 @@
             }
 
             @Override
-            public void onVolumeMetadataChanged(VolumeInfo vol) throws RemoteException {
+            public void onVolumeMetadataChanged(String fsUuid) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
-                    _data.writeParcelable(vol, 0);
+                    _data.writeString(fsUuid);
                     mRemote.transact(Stub.TRANSACTION_onVolumeMetadataChanged, _data, _reply,
                             android.os.IBinder.FLAG_ONEWAY);
                     _reply.readException();
@@ -253,7 +253,7 @@
     public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
             throws RemoteException;
 
-    public void onVolumeMetadataChanged(VolumeInfo vol) throws RemoteException;
+    public void onVolumeMetadataChanged(String fsUuid) throws RemoteException;
 
     public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageEventListener.java b/core/java/android/os/storage/StorageEventListener.java
index 6a0140e..536aca9 100644
--- a/core/java/android/os/storage/StorageEventListener.java
+++ b/core/java/android/os/storage/StorageEventListener.java
@@ -41,7 +41,7 @@
     public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
     }
 
-    public void onVolumeMetadataChanged(VolumeInfo vol) {
+    public void onVolumeMetadataChanged(String fsUuid) {
     }
 
     public void onDiskScanned(DiskInfo disk, int volumeCount) {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 6116aef..29da4f1 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -34,6 +34,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.os.SomeArgs;
@@ -79,9 +80,6 @@
     /** {@hide} */
     public static final String UUID_PRIMARY_PHYSICAL = "primary_physical";
 
-    /** {@hide} */
-    public static final int FLAG_ALL_METADATA = 1 << 0;
-
     private final Context mContext;
     private final ContentResolver mResolver;
 
@@ -120,7 +118,7 @@
                     args.recycle();
                     return true;
                 case MSG_VOLUME_METADATA_CHANGED:
-                    mCallback.onVolumeMetadataChanged((VolumeInfo) args.arg1);
+                    mCallback.onVolumeMetadataChanged((String) args.arg1);
                     args.recycle();
                     return true;
                 case MSG_DISK_SCANNED:
@@ -156,9 +154,9 @@
         }
 
         @Override
-        public void onVolumeMetadataChanged(VolumeInfo vol) {
+        public void onVolumeMetadataChanged(String fsUuid) {
             final SomeArgs args = SomeArgs.obtain();
-            args.arg1 = vol;
+            args.arg1 = fsUuid;
             mHandler.obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget();
         }
 
@@ -516,6 +514,18 @@
     }
 
     /** {@hide} */
+    public @Nullable VolumeRecord findRecordByUuid(String fsUuid) {
+        Preconditions.checkNotNull(fsUuid);
+        // TODO; go directly to service to make this faster
+        for (VolumeRecord rec : getVolumeRecords()) {
+            if (Objects.equals(rec.fsUuid, fsUuid)) {
+                return rec;
+            }
+        }
+        return null;
+    }
+
+    /** {@hide} */
     public @Nullable VolumeInfo findPrivateForEmulated(VolumeInfo emulatedVol) {
         return findVolumeById(emulatedVol.getId().replace("emulated", "private"));
     }
@@ -527,13 +537,17 @@
 
     /** {@hide} */
     public @NonNull List<VolumeInfo> getVolumes() {
-        return getVolumes(0);
+        try {
+            return Arrays.asList(mMountService.getVolumes(0));
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
     }
 
     /** {@hide} */
-    public @NonNull List<VolumeInfo> getVolumes(int flags) {
+    public @NonNull List<VolumeRecord> getVolumeRecords() {
         try {
-            return Arrays.asList(mMountService.getVolumes(flags));
+            return Arrays.asList(mMountService.getVolumeRecords(0));
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -541,13 +555,23 @@
 
     /** {@hide} */
     public @Nullable String getBestVolumeDescription(VolumeInfo vol) {
-        String descrip = vol.getDescription();
-        if (vol.disk != null) {
-            if (TextUtils.isEmpty(descrip)) {
-                descrip = vol.disk.getDescription();
+        // Nickname always takes precedence when defined
+        if (!TextUtils.isEmpty(vol.fsUuid)) {
+            final VolumeRecord rec = findRecordByUuid(vol.fsUuid);
+            if (!TextUtils.isEmpty(rec.nickname)) {
+                return rec.nickname;
             }
         }
-        return descrip;
+
+        if (!TextUtils.isEmpty(vol.getDescription())) {
+            return vol.getDescription();
+        }
+
+        if (vol.disk != null) {
+            return vol.disk.getDescription();
+        }
+
+        return null;
     }
 
     /** {@hide} */
@@ -616,29 +640,62 @@
     }
 
     /** {@hide} */
-    public void setVolumeNickname(String volId, String nickname) {
+    public void wipeAdoptableDisks() {
+        // We only wipe devices in "adoptable" locations, which are in a
+        // long-term stable slot/location on the device, where apps have a
+        // reasonable chance of storing sensitive data. (Apps need to go through
+        // SAF to write to transient volumes.)
+        final List<DiskInfo> disks = getDisks();
+        for (DiskInfo disk : disks) {
+            final String diskId = disk.getId();
+            if (disk.isAdoptable()) {
+                Slog.d(TAG, "Found adoptable " + diskId + "; wiping");
+                try {
+                    // TODO: switch to explicit wipe command when we have it,
+                    // for now rely on the fact that vfat format does a wipe
+                    mMountService.partitionPublic(diskId);
+                } catch (Exception e) {
+                    Slog.w(TAG, "Failed to wipe " + diskId + ", but soldiering onward", e);
+                }
+            } else {
+                Slog.d(TAG, "Ignorning non-adoptable disk " + disk.getId());
+            }
+        }
+    }
+
+    /** {@hide} */
+    public void setVolumeNickname(String fsUuid, String nickname) {
         try {
-            mMountService.setVolumeNickname(volId, nickname);
+            mMountService.setVolumeNickname(fsUuid, nickname);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
     }
 
     /** {@hide} */
-    public void setVolumeInited(String volId, boolean inited) {
+    public void setVolumeInited(String fsUuid, boolean inited) {
         try {
-            mMountService.setVolumeUserFlags(volId, inited ? VolumeInfo.USER_FLAG_INITED : 0,
-                    VolumeInfo.USER_FLAG_INITED);
+            mMountService.setVolumeUserFlags(fsUuid, inited ? VolumeRecord.USER_FLAG_INITED : 0,
+                    VolumeRecord.USER_FLAG_INITED);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
     }
 
     /** {@hide} */
-    public void setVolumeSnoozed(String volId, boolean snoozed) {
+    public void setVolumeSnoozed(String fsUuid, boolean snoozed) {
         try {
-            mMountService.setVolumeUserFlags(volId, snoozed ? VolumeInfo.USER_FLAG_SNOOZED : 0,
-                    VolumeInfo.USER_FLAG_SNOOZED);
+            mMountService.setVolumeUserFlags(fsUuid, snoozed ? VolumeRecord.USER_FLAG_SNOOZED : 0,
+                    VolumeRecord.USER_FLAG_SNOOZED);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /** {@hide} */
+    public void forgetVolume(String fsUuid) {
+        try {
+            mMountService.forgetVolume(fsUuid);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 4e9cfc7..fd10cae 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -78,9 +78,6 @@
     public static final int MOUNT_FLAG_PRIMARY = 1 << 0;
     public static final int MOUNT_FLAG_VISIBLE = 1 << 1;
 
-    public static final int USER_FLAG_INITED = 1 << 0;
-    public static final int USER_FLAG_SNOOZED = 1 << 1;
-
     private static SparseArray<String> sStateToEnvironment = new SparseArray<>();
     private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>();
 
@@ -135,8 +132,6 @@
 
     /** Framework state */
     public final int mtpIndex;
-    public String nickname;
-    public int userFlags = 0;
 
     public VolumeInfo(String id, int type, DiskInfo disk, int mtpIndex) {
         this.id = Preconditions.checkNotNull(id);
@@ -161,8 +156,6 @@
         fsLabel = parcel.readString();
         path = parcel.readString();
         mtpIndex = parcel.readInt();
-        nickname = parcel.readString();
-        userFlags = parcel.readInt();
     }
 
     public static @NonNull String getEnvironmentForState(int state) {
@@ -210,10 +203,6 @@
         return fsUuid;
     }
 
-    public @Nullable String getNickname() {
-        return nickname;
-    }
-
     public int getMountUserId() {
         return mountUserId;
     }
@@ -221,8 +210,6 @@
     public @Nullable String getDescription() {
         if (ID_PRIVATE_INTERNAL.equals(id)) {
             return Resources.getSystem().getString(com.android.internal.R.string.storage_internal);
-        } else if (!TextUtils.isEmpty(nickname)) {
-            return nickname;
         } else if (!TextUtils.isEmpty(fsLabel)) {
             return fsLabel;
         } else {
@@ -250,14 +237,6 @@
         return (mountFlags & MOUNT_FLAG_VISIBLE) != 0;
     }
 
-    public boolean isInited() {
-        return (userFlags & USER_FLAG_INITED) != 0;
-    }
-
-    public boolean isSnoozed() {
-        return (userFlags & USER_FLAG_SNOOZED) != 0;
-    }
-
     public boolean isVisibleToUser(int userId) {
         if (type == TYPE_PUBLIC && userId == this.mountUserId) {
             return isVisible();
@@ -394,8 +373,6 @@
         pw.println();
         pw.printPair("path", path);
         pw.printPair("mtpIndex", mtpIndex);
-        pw.printPair("nickname", nickname);
-        pw.printPair("userFlags", DebugUtils.flagsToString(getClass(), "USER_FLAG_", userFlags));
         pw.decreaseIndent();
         pw.println();
     }
@@ -461,7 +438,5 @@
         parcel.writeString(fsLabel);
         parcel.writeString(path);
         parcel.writeInt(mtpIndex);
-        parcel.writeString(nickname);
-        parcel.writeInt(userFlags);
     }
 }
diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java
new file mode 100644
index 0000000..096e2dd
--- /dev/null
+++ b/core/java/android/os/storage/VolumeRecord.java
@@ -0,0 +1,139 @@
+/*
+ * 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 android.os.storage;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.DebugUtils;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * Metadata for a storage volume which may not be currently present.
+ *
+ * @hide
+ */
+public class VolumeRecord implements Parcelable {
+    public static final String EXTRA_FS_UUID =
+            "android.os.storage.extra.FS_UUID";
+
+    public static final int USER_FLAG_INITED = 1 << 0;
+    public static final int USER_FLAG_SNOOZED = 1 << 1;
+
+    public final int type;
+    public final String fsUuid;
+    public String nickname;
+    public int userFlags;
+
+    public VolumeRecord(int type, String fsUuid) {
+        this.type = type;
+        this.fsUuid = Preconditions.checkNotNull(fsUuid);
+    }
+
+    public VolumeRecord(Parcel parcel) {
+        type = parcel.readInt();
+        fsUuid = parcel.readString();
+        nickname = parcel.readString();
+        userFlags = parcel.readInt();
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public String getFsUuid() {
+        return fsUuid;
+    }
+
+    public String getNickname() {
+        return nickname;
+    }
+
+    public boolean isInited() {
+        return (userFlags & USER_FLAG_INITED) != 0;
+    }
+
+    public boolean isSnoozed() {
+        return (userFlags & USER_FLAG_SNOOZED) != 0;
+    }
+
+    public void dump(IndentingPrintWriter pw) {
+        pw.println("VolumeRecord:");
+        pw.increaseIndent();
+        pw.printPair("type", DebugUtils.valueToString(VolumeInfo.class, "TYPE_", type));
+        pw.printPair("fsUuid", fsUuid);
+        pw.printPair("nickname", nickname);
+        pw.printPair("userFlags",
+                DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags));
+        pw.decreaseIndent();
+        pw.println();
+    }
+
+    @Override
+    public VolumeRecord clone() {
+        final Parcel temp = Parcel.obtain();
+        try {
+            writeToParcel(temp, 0);
+            temp.setDataPosition(0);
+            return CREATOR.createFromParcel(temp);
+        } finally {
+            temp.recycle();
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof VolumeRecord) {
+            return Objects.equals(fsUuid, ((VolumeRecord) o).fsUuid);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return fsUuid.hashCode();
+    }
+
+    public static final Creator<VolumeRecord> CREATOR = new Creator<VolumeRecord>() {
+        @Override
+        public VolumeRecord createFromParcel(Parcel in) {
+            return new VolumeRecord(in);
+        }
+
+        @Override
+        public VolumeRecord[] newArray(int size) {
+            return new VolumeRecord[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(type);
+        parcel.writeString(fsUuid);
+        parcel.writeString(nickname);
+        parcel.writeInt(userFlags);
+    }
+}
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
index b3a3aad..458f153 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.java
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -105,11 +105,11 @@
         }
     }
 
-    public boolean getBoolean(KeyCharacteristics keyCharacteristics, int tag) {
-        if (keyCharacteristics.hwEnforced.containsTag(tag)) {
-            return keyCharacteristics.hwEnforced.getBoolean(tag, false);
+    public boolean getBoolean(int tag) {
+        if (hwEnforced.containsTag(tag)) {
+            return hwEnforced.getBoolean(tag, false);
         } else {
-            return keyCharacteristics.swEnforced.getBoolean(tag, false);
+            return swEnforced.getBoolean(tag, false);
         }
     }
 }
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 14e947c..dc8f3ea 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -62,7 +62,7 @@
             Calendar.WEDNESDAY, Calendar.THURSDAY };
     public static final int[] WEEKEND_DAYS = { Calendar.FRIDAY, Calendar.SATURDAY };
 
-    public static final int[] MINUTE_BUCKETS = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
+    public static final int[] MINUTE_BUCKETS = generateMinuteBuckets();
     private static final int SECONDS_MS = 1000;
     private static final int MINUTES_MS = 60 * SECONDS_MS;
     private static final int ZERO_VALUE_MS = 10 * SECONDS_MS;
@@ -201,6 +201,18 @@
         }
     }
 
+    private static int[] generateMinuteBuckets() {
+        final int maxHrs = 12;
+        final int[] buckets = new int[maxHrs + 3];
+        buckets[0] = 15;
+        buckets[1] = 30;
+        buckets[2] = 45;
+        for (int i = 1; i <= maxHrs; i++) {
+            buckets[2 + i] = 60 * i;
+        }
+        return buckets;
+    }
+
     public static String sourceToString(int source) {
         switch (source) {
             case SOURCE_ANYONE:
@@ -298,10 +310,10 @@
                         throw new IndexOutOfBoundsException("bad source in config:" + rt.allowFrom);
                     }
                 } else if (MANUAL_TAG.equals(tag)) {
-                    rt.manualRule = readRuleXml(parser);
+                    rt.manualRule = readRuleXml(parser, false /*conditionRequired*/);
                 } else if (AUTOMATIC_TAG.equals(tag)) {
                     final String id = parser.getAttributeValue(null, RULE_ATT_ID);
-                    final ZenRule automaticRule = readRuleXml(parser);
+                    final ZenRule automaticRule = readRuleXml(parser, true /*conditionRequired*/);
                     if (id != null && automaticRule != null) {
                         rt.automaticRules.put(id, automaticRule);
                     }
@@ -341,7 +353,7 @@
         out.endTag(null, ZEN_TAG);
     }
 
-    public static ZenRule readRuleXml(XmlPullParser parser) {
+    public static ZenRule readRuleXml(XmlPullParser parser, boolean conditionRequired) {
         final ZenRule rt = new ZenRule();
         rt.enabled = safeBoolean(parser, RULE_ATT_ENABLED, true);
         rt.snoozing = safeBoolean(parser, RULE_ATT_SNOOZING, false);
@@ -355,7 +367,7 @@
         rt.conditionId = safeUri(parser, RULE_ATT_CONDITION_ID);
         rt.component = safeComponentName(parser, RULE_ATT_COMPONENT);
         rt.condition = readConditionXml(parser);
-        return rt.condition != null ? rt : null;
+        return rt.condition != null || !conditionRequired ? rt : null;
     }
 
     public static void writeRuleXml(ZenRule rule, XmlSerializer out) throws IOException {
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index a7d9503a..ca37d49 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -214,7 +214,7 @@
                         sConstructors.put(className, constructor);
                     }
                 }
-
+                constructor.setAccessible(true);
                 return constructor.newInstance(mContext, attrs);
             }
         } catch (InstantiationException e) {
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index aefced8..558b8f5 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -74,6 +74,7 @@
         private static final byte LONG_TYPE   = 1;
         private static final byte STRING_TYPE = 2;
         private static final byte LIST_TYPE   = 3;
+        private static final byte FLOAT_TYPE = 4;
 
         /** @param data containing event, read from the system */
         /*package*/ Event(byte[] data) {
@@ -106,7 +107,7 @@
             return mBuffer.getInt(offset);
         }
 
-        /** @return one of Integer, Long, String, null, or Object[] of same. */
+        /** @return one of Integer, Long, Float, String, null, or Object[] of same. */
         public synchronized Object getData() {
             try {
                 int offset = mBuffer.getShort(HEADER_SIZE_OFFSET);
@@ -130,10 +131,13 @@
             byte type = mBuffer.get();
             switch (type) {
             case INT_TYPE:
-                return (Integer) mBuffer.getInt();
+                return mBuffer.getInt();
 
             case LONG_TYPE:
-                return (Long) mBuffer.getLong();
+                return mBuffer.getLong();
+
+            case FLOAT_TYPE:
+                return mBuffer.getFloat();
 
             case STRING_TYPE:
                 try {
@@ -180,6 +184,14 @@
     /**
      * Record an event log message.
      * @param tag The event type tag code
+     * @param value A value to log
+     * @return The number of bytes written
+     */
+    public static native int writeEvent(int tag, float value);
+
+    /**
+     * Record an event log message.
+     * @param tag The event type tag code
      * @param str A value to log
      * @return The number of bytes written
      */
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index eedbc70..46dd857 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -234,25 +234,13 @@
      * Draws the specified display list onto this canvas. The display list can only
      * be drawn if {@link android.view.RenderNode#isValid()} returns true.
      *
-     * @param renderNode The RenderNode to replay.
+     * @param renderNode The RenderNode to draw.
      */
     public void drawRenderNode(RenderNode renderNode) {
-        drawRenderNode(renderNode, RenderNode.FLAG_CLIP_CHILDREN);
+        nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList());
     }
 
-    /**
-     * Draws the specified display list onto this canvas.
-     *
-     * @param renderNode The RenderNode to replay.
-     * @param flags Optional flags about drawing, see {@link RenderNode} for
-     *              the possible flags.
-     */
-    public void drawRenderNode(RenderNode renderNode, int flags) {
-        nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList(), flags);
-    }
-
-    private static native void nDrawRenderNode(long renderer, long renderNode,
-            int flags);
+    private static native void nDrawRenderNode(long renderer, long renderNode);
 
     ///////////////////////////////////////////////////////////////////////////
     // Hardware layer
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index 794c8e7..a3e7a10 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -3599,7 +3599,7 @@
         if (!mForcedNavigationBarColor) {
             mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
         }
-        if (a.getBoolean(R.styleable.Window_windowHasLightStatusBar, false)) {
+        if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
             decor.setSystemUiVisibility(
                     decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
         }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a0220a0..e8fc15e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -30,6 +30,7 @@
 import android.annotation.Size;
 import android.content.ClipData;
 import android.content.Context;
+import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -2591,7 +2592,7 @@
      * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS
      *         FLAG_TRANSLUCENT_STATUS}.
      *
-     * @see android.R.attr#windowHasLightStatusBar
+     * @see android.R.attr#windowLightStatusBar
      */
     public static final int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
 
@@ -4016,37 +4017,7 @@
 
                     final String handlerName = a.getString(attr);
                     if (handlerName != null) {
-                        setOnClickListener(new OnClickListener() {
-                            private Method mHandler;
-
-                            public void onClick(View v) {
-                                if (mHandler == null) {
-                                    try {
-                                        mHandler = getContext().getClass().getMethod(handlerName,
-                                                View.class);
-                                    } catch (NoSuchMethodException e) {
-                                        int id = getId();
-                                        String idText = id == NO_ID ? "" : " with id '"
-                                                + getContext().getResources().getResourceEntryName(
-                                                    id) + "'";
-                                        throw new IllegalStateException("Could not find a method " +
-                                                handlerName + "(View) in the activity "
-                                                + getContext().getClass() + " for onClick handler"
-                                                + " on view " + View.this.getClass() + idText, e);
-                                    }
-                                }
-
-                                try {
-                                    mHandler.invoke(getContext(), View.this);
-                                } catch (IllegalAccessException e) {
-                                    throw new IllegalStateException("Could not execute non "
-                                            + "public method of the activity", e);
-                                } catch (InvocationTargetException e) {
-                                    throw new IllegalStateException("Could not execute "
-                                            + "method of the activity", e);
-                                }
-                            }
-                        });
+                        setOnClickListener(new DeclaredOnClickListener(this, handlerName));
                     }
                     break;
                 case R.styleable.View_overScrollMode:
@@ -4238,6 +4209,66 @@
     }
 
     /**
+     * An implementation of OnClickListener that attempts to lazily load a
+     * named click handling method from a parent or ancestor context.
+     */
+    private static class DeclaredOnClickListener implements OnClickListener {
+        private final View mHostView;
+        private final String mMethodName;
+
+        private Method mMethod;
+
+        public DeclaredOnClickListener(@NonNull View hostView, @NonNull String methodName) {
+            mHostView = hostView;
+            mMethodName = methodName;
+        }
+
+        @Override
+        public void onClick(@NonNull View v) {
+            if (mMethod == null) {
+                mMethod = resolveMethod(mHostView.getContext(), mMethodName);
+            }
+
+            try {
+                mMethod.invoke(mHostView.getContext(), v);
+            } catch (IllegalAccessException e) {
+                throw new IllegalStateException(
+                        "Could not execute non-public method for android:onClick", e);
+            } catch (InvocationTargetException e) {
+                throw new IllegalStateException(
+                        "Could not execute method for android:onClick", e);
+            }
+        }
+
+        @NonNull
+        private Method resolveMethod(@Nullable Context context, @NonNull String name) {
+            while (context != null) {
+                try {
+                    if (!context.isRestricted()) {
+                        return context.getClass().getMethod(mMethodName, View.class);
+                    }
+                } catch (NoSuchMethodException e) {
+                    // Failed to find method, keep searching up the hierarchy.
+                }
+
+                if (context instanceof ContextWrapper) {
+                    context = ((ContextWrapper) context).getBaseContext();
+                } else {
+                    // Can't search up the hierarchy, null out and fail.
+                    context = null;
+                }
+            }
+
+            final int id = mHostView.getId();
+            final String idText = id == NO_ID ? "" : " with id '"
+                    + mHostView.getContext().getResources().getResourceEntryName(id) + "'";
+            throw new IllegalStateException("Could not find method " + mMethodName
+                    + "(View) in a parent or ancestor Context for android:onClick "
+                    + "attribute defined on view " + mHostView.getClass() + idText);
+        }
+    }
+
+    /**
      * Non-public constructor for use in testing
      */
     View() {
@@ -15500,7 +15531,7 @@
         if (!drawingWithDrawingCache) {
             if (drawingWithRenderNode) {
                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
-                ((DisplayListCanvas) canvas).drawRenderNode(renderNode, parentFlags);
+                ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
             } else {
                 // Fast path for layouts with no backgrounds
                 if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
@@ -15769,11 +15800,7 @@
             return;
         }
 
-        if (mBackgroundSizeChanged) {
-            background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
-            mBackgroundSizeChanged = false;
-            rebuildOutline();
-        }
+        setBackgroundBounds();
 
         // Attempt to use a display list if requested.
         if (canvas.isHardwareAccelerated() && mAttachInfo != null
@@ -15799,6 +15826,19 @@
         }
     }
 
+    /**
+     * Sets the correct background bounds and rebuilds the outline, if needed.
+     * <p/>
+     * This is called by LayoutLib.
+     */
+    void setBackgroundBounds() {
+        if (mBackgroundSizeChanged && mBackground != null) {
+            mBackground.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
+            mBackgroundSizeChanged = false;
+            rebuildOutline();
+        }
+    }
+
     private void setBackgroundRenderNodeProperties(RenderNode renderNode) {
         renderNode.setTranslationX(mScrollX);
         renderNode.setTranslationY(mScrollY);
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 478fa00..d271af2 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -286,14 +286,10 @@
         return null;
     }
 
-    private boolean isCalendarInRange(Calendar value) {
-        return value.compareTo(mMinDate) >= 0 && value.compareTo(mMaxDate) <= 0;
-    }
-
     private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() {
         @Override
         public void onDayClick(SimpleMonthView view, Calendar day) {
-            if (day != null && isCalendarInRange(day)) {
+            if (day != null) {
                 setSelectedDay(day);
 
                 if (mOnDaySelectedListener != null) {
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index 113e597..334afab 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -178,6 +178,13 @@
         });
     }
 
+    private void updateButtonVisibility(int position) {
+        final boolean hasPrev = position > 0;
+        final boolean hasNext = position < (mAdapter.getCount() - 1);
+        mPrevButton.setVisibility(hasPrev ? View.VISIBLE : View.INVISIBLE);
+        mNextButton.setVisibility(hasNext ? View.VISIBLE : View.INVISIBLE);
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         final ViewPager viewPager = mViewPager;
@@ -218,12 +225,6 @@
         final int height = bottom - top;
         mViewPager.layout(0, 0, width, height);
 
-        if (mViewPager.getChildCount() < 1) {
-            leftButton.setVisibility(View.INVISIBLE);
-            rightButton.setVisibility(View.INVISIBLE);
-            return;
-        }
-
         final SimpleMonthView monthView = (SimpleMonthView) mViewPager.getChildAt(0);
         final int monthHeight = monthView.getMonthHeight();
         final int cellWidth = monthView.getCellWidth();
@@ -235,7 +236,6 @@
         final int leftIconTop = monthView.getPaddingTop() + (monthHeight - leftDH) / 2;
         final int leftIconLeft = monthView.getPaddingLeft() + (cellWidth - leftDW) / 2;
         leftButton.layout(leftIconLeft, leftIconTop, leftIconLeft + leftDW, leftIconTop + leftDH);
-        leftButton.setVisibility(View.VISIBLE);
 
         final int rightDW = rightButton.getMeasuredWidth();
         final int rightDH = rightButton.getMeasuredHeight();
@@ -243,7 +243,6 @@
         final int rightIconRight = width - monthView.getPaddingRight() - (cellWidth - rightDW) / 2;
         rightButton.layout(rightIconRight - rightDW, rightIconTop,
                 rightIconRight, rightIconTop + rightDH);
-        rightButton.setVisibility(View.VISIBLE);
     }
 
     public void setDayOfWeekTextAppearance(int resId) {
@@ -399,10 +398,7 @@
 
         @Override
         public void onPageSelected(int position) {
-            mPrevButton.setVisibility(
-                    position > 0 ? View.VISIBLE : View.INVISIBLE);
-            mNextButton.setVisibility(
-                    position < (mAdapter.getCount() - 1) ? View.VISIBLE : View.INVISIBLE);
+            updateButtonVisibility(position);
         }
     };
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index f1be434..089074a 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -145,16 +145,16 @@
     InputContentType mInputContentType;
     InputMethodState mInputMethodState;
 
-    private static class TextDisplayList {
-        RenderNode displayList;
+    private static class TextRenderNode {
+        RenderNode renderNode;
         boolean isDirty;
-        public TextDisplayList(String name) {
+        public TextRenderNode(String name) {
             isDirty = true;
-            displayList = RenderNode.create(name, null);
+            renderNode = RenderNode.create(name, null);
         }
-        boolean needsRecord() { return isDirty || !displayList.isValid(); }
+        boolean needsRecord() { return isDirty || !renderNode.isValid(); }
     }
-    TextDisplayList[] mTextDisplayLists;
+    TextRenderNode[] mTextRenderNodes;
 
     boolean mFrozenWithFocus;
     boolean mSelectionMoved;
@@ -360,10 +360,10 @@
     }
 
     private void destroyDisplayListsData() {
-        if (mTextDisplayLists != null) {
-            for (int i = 0; i < mTextDisplayLists.length; i++) {
-                RenderNode displayList = mTextDisplayLists[i] != null
-                        ? mTextDisplayLists[i].displayList : null;
+        if (mTextRenderNodes != null) {
+            for (int i = 0; i < mTextRenderNodes.length; i++) {
+                RenderNode displayList = mTextRenderNodes[i] != null
+                        ? mTextRenderNodes[i].renderNode : null;
                 if (displayList != null && displayList.isValid()) {
                     displayList.destroyDisplayListData();
                 }
@@ -1467,8 +1467,8 @@
                 firstLine, lastLine);
 
         if (layout instanceof DynamicLayout) {
-            if (mTextDisplayLists == null) {
-                mTextDisplayLists = ArrayUtils.emptyArray(TextDisplayList.class);
+            if (mTextRenderNodes == null) {
+                mTextRenderNodes = ArrayUtils.emptyArray(TextRenderNode.class);
             }
 
             DynamicLayout dynamicLayout = (DynamicLayout) layout;
@@ -1489,19 +1489,19 @@
                             searchStartIndex);
                     // Note how dynamic layout's internal block indices get updated from Editor
                     blockIndices[i] = blockIndex;
-                    if (mTextDisplayLists[blockIndex] != null) {
-                        mTextDisplayLists[blockIndex].isDirty = true;
+                    if (mTextRenderNodes[blockIndex] != null) {
+                        mTextRenderNodes[blockIndex].isDirty = true;
                     }
                     searchStartIndex = blockIndex + 1;
                 }
 
-                if (mTextDisplayLists[blockIndex] == null) {
-                    mTextDisplayLists[blockIndex] =
-                            new TextDisplayList("Text " + blockIndex);
+                if (mTextRenderNodes[blockIndex] == null) {
+                    mTextRenderNodes[blockIndex] =
+                            new TextRenderNode("Text " + blockIndex);
                 }
 
-                final boolean blockDisplayListIsInvalid = mTextDisplayLists[blockIndex].needsRecord();
-                RenderNode blockDisplayList = mTextDisplayLists[blockIndex].displayList;
+                final boolean blockDisplayListIsInvalid = mTextRenderNodes[blockIndex].needsRecord();
+                RenderNode blockDisplayList = mTextRenderNodes[blockIndex].renderNode;
                 if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
                     final int blockBeginLine = endOfPreviousBlock + 1;
                     final int top = layout.getLineTop(blockBeginLine);
@@ -1528,7 +1528,7 @@
                             // brings this range of text back to the top left corner of the viewport
                             displayListCanvas.translate(-left, -top);
                             layout.drawText(displayListCanvas, blockBeginLine, blockEndLine);
-                            mTextDisplayLists[blockIndex].isDirty = false;
+                            mTextRenderNodes[blockIndex].isDirty = false;
                             // No need to untranslate, previous context is popped after
                             // drawDisplayList
                         } finally {
@@ -1543,8 +1543,7 @@
                     blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
                 }
 
-                ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList,
-                        0 /* no child clipping, our TextView parent enforces it */);
+                ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList);
 
                 endOfPreviousBlock = blockEndLine;
             }
@@ -1558,7 +1557,7 @@
 
     private int getAvailableDisplayListIndex(int[] blockIndices, int numberOfBlocks,
             int searchStartIndex) {
-        int length = mTextDisplayLists.length;
+        int length = mTextRenderNodes.length;
         for (int i = searchStartIndex; i < length; i++) {
             boolean blockIndexFound = false;
             for (int j = 0; j < numberOfBlocks; j++) {
@@ -1572,7 +1571,7 @@
         }
 
         // No available index found, the pool has to grow
-        mTextDisplayLists = GrowingArrayUtils.append(mTextDisplayLists, length, null);
+        mTextRenderNodes = GrowingArrayUtils.append(mTextRenderNodes, length, null);
         return length;
     }
 
@@ -1589,7 +1588,7 @@
      * Invalidates all the sub-display lists that overlap the specified character range
      */
     void invalidateTextDisplayList(Layout layout, int start, int end) {
-        if (mTextDisplayLists != null && layout instanceof DynamicLayout) {
+        if (mTextRenderNodes != null && layout instanceof DynamicLayout) {
             final int firstLine = layout.getLineForOffset(start);
             final int lastLine = layout.getLineForOffset(end);
 
@@ -1609,7 +1608,7 @@
             while (i < numberOfBlocks) {
                 final int blockIndex = blockIndices[i];
                 if (blockIndex != DynamicLayout.INVALID_BLOCK_INDEX) {
-                    mTextDisplayLists[blockIndex].isDirty = true;
+                    mTextRenderNodes[blockIndex].isDirty = true;
                 }
                 if (blockEndLines[i] >= lastLine) break;
                 i++;
@@ -1618,9 +1617,9 @@
     }
 
     void invalidateTextDisplayList() {
-        if (mTextDisplayLists != null) {
-            for (int i = 0; i < mTextDisplayLists.length; i++) {
-                if (mTextDisplayLists[i] != null) mTextDisplayLists[i].isDirty = true;
+        if (mTextRenderNodes != null) {
+            for (int i = 0; i < mTextRenderNodes.length; i++) {
+                if (mTextRenderNodes[i] != null) mTextRenderNodes[i].isDirty = true;
             }
         }
     }
@@ -3563,7 +3562,7 @@
                 return false;
             }
 
-            return isPositionVisible(mPositionX + mHotspotX, mPositionY);
+            return isPositionVisible(mPositionX + mHotspotX + getHorizontalOffset(), mPositionY);
         }
 
         public abstract int getCurrentCursorOffset();
@@ -4491,7 +4490,7 @@
 
     private class CorrectionHighlighter {
         private final Path mPath = new Path();
-        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        private final Paint mPaint = new Paint();
         private int mStart, mEnd;
         private long mFadingStartTime;
         private RectF mTempRectF;
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 2375089..8d8b3a3 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -326,6 +326,16 @@
             if (mFfwdButton != null && !mPlayer.canSeekForward()) {
                 mFfwdButton.setEnabled(false);
             }
+            // TODO What we really should do is add a canSeek to the MediaPlayerControl interface;
+            // this scheme can break the case when applications want to allow seek through the
+            // progress bar but disable forward/backward buttons.
+            //
+            // However, currently the flags SEEK_BACKWARD_AVAILABLE, SEEK_FORWARD_AVAILABLE,
+            // and SEEK_AVAILABLE are all (un)set together; as such the aforementioned issue
+            // shouldn't arise in existing applications.
+            if (mProgress != null && !mPlayer.canSeekBackward() && !mPlayer.canSeekForward()) {
+                mProgress.setEnabled(false);
+            }
         } catch (IncompatibleClassChangeError ex) {
             // We were given an old version of the interface, that doesn't have
             // the canPause/canSeekXYZ methods. This is OK, it just means we
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 2778f0f..acf1df9 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -31,6 +31,7 @@
 import android.text.format.DateFormat;
 import android.util.AttributeSet;
 import android.util.IntArray;
+import android.util.MathUtils;
 import android.util.StateSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -422,7 +423,8 @@
 
             int stateMask = 0;
 
-            if (day >= mEnabledDayStart && day <= mEnabledDayEnd) {
+            final boolean isDayEnabled = isDayEnabled(day);
+            if (isDayEnabled) {
                 stateMask |= StateSet.VIEW_STATE_ENABLED;
             }
 
@@ -435,8 +437,11 @@
             } else if (mTouchedItem == day) {
                 stateMask |= StateSet.VIEW_STATE_PRESSED;
 
-                // Adjust the circle to be centered on the row.
-                canvas.drawCircle(colCenterRtl, rowCenter, mDaySelectorRadius, mDayHighlightPaint);
+                if (isDayEnabled) {
+                    // Adjust the circle to be centered on the row.
+                    canvas.drawCircle(colCenterRtl, rowCenter,
+                            mDaySelectorRadius, mDayHighlightPaint);
+                }
             }
 
             final boolean isDayToday = mToday == day;
@@ -460,6 +465,14 @@
         }
     }
 
+    private boolean isDayEnabled(int day) {
+        return day >= mEnabledDayStart && day <= mEnabledDayEnd;
+    }
+
+    private boolean isValidDayOfMonth(int day) {
+        return day >= 1 && day <= mDaysInMonth;
+    }
+
     private static boolean isValidDayOfWeek(int day) {
         return day >= Calendar.SUNDAY && day <= Calendar.SATURDAY;
     }
@@ -536,13 +549,6 @@
             mWeekStart = mCalendar.getFirstDayOfWeek();
         }
 
-        if (enabledDayStart > 0 && enabledDayEnd < 32) {
-            mEnabledDayStart = enabledDayStart;
-        }
-        if (enabledDayEnd > 0 && enabledDayEnd < 32 && enabledDayEnd >= enabledDayStart) {
-            mEnabledDayEnd = enabledDayEnd;
-        }
-
         // Figure out what day today is.
         final Calendar today = Calendar.getInstance();
         mToday = -1;
@@ -554,6 +560,9 @@
             }
         }
 
+        mEnabledDayStart = MathUtils.constrain(enabledDayStart, 1, mDaysInMonth);
+        mEnabledDayEnd = MathUtils.constrain(enabledDayEnd, mEnabledDayStart, mDaysInMonth);
+
         // Invalidate the old title.
         mTitle = null;
 
@@ -694,7 +703,7 @@
         final int col = (paddedXRtl * DAYS_IN_WEEK) / mPaddedWidth;
         final int index = col + row * DAYS_IN_WEEK;
         final int day = index + 1 - findDayOffset();
-        if (day < 1 || day > mDaysInMonth) {
+        if (!isValidDayOfMonth(day)) {
             return -1;
         }
 
@@ -708,7 +717,7 @@
      * @param outBounds the rect to populate with bounds
      */
     private boolean getBoundsForDay(int id, Rect outBounds) {
-        if (id < 1 || id > mDaysInMonth) {
+        if (!isValidDayOfMonth(id)) {
             return false;
         }
 
@@ -742,7 +751,7 @@
      * @param day the day that was clicked
      */
     private boolean onDayClicked(int day) {
-        if (day < 0 || day > mDaysInMonth) {
+        if (!isValidDayOfMonth(day) || !isDayEnabled(day)) {
             return false;
         }
 
@@ -774,7 +783,7 @@
         @Override
         protected int getVirtualViewAt(float x, float y) {
             final int day = getDayAtLocation((int) (x + 0.5f), (int) (y + 0.5f));
-            if (day >= 0) {
+            if (day != -1) {
                 return day;
             }
             return ExploreByTouchHelper.INVALID_ID;
@@ -808,7 +817,13 @@
             node.setText(getDayText(virtualViewId));
             node.setContentDescription(getDayDescription(virtualViewId));
             node.setBoundsInParent(mTempRect);
-            node.addAction(AccessibilityAction.ACTION_CLICK);
+
+            final boolean isDayEnabled = isDayEnabled(virtualViewId);
+            if (isDayEnabled) {
+                node.addAction(AccessibilityAction.ACTION_CLICK);
+            }
+
+            node.setEnabled(isDayEnabled);
 
             if (virtualViewId == mActivatedDay) {
                 // TODO: This should use activated once that's supported.
@@ -835,7 +850,7 @@
          * @return a description of the virtual view
          */
         private CharSequence getDayDescription(int id) {
-            if (id >= 1 && id <= mDaysInMonth) {
+            if (isValidDayOfMonth(id)) {
                 mTempCalendar.set(mYear, mMonth, id);
                 return DateFormat.format(DATE_FORMAT, mTempCalendar.getTimeInMillis());
             }
@@ -850,7 +865,7 @@
          * @return the visible text of the virtual view
          */
         private CharSequence getDayText(int id) {
-            if (id >= 1 && id <= mDaysInMonth) {
+            if (isValidDayOfMonth(id)) {
                 return Integer.toString(id);
             }
 
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index ae779fe..f94f97c 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -216,7 +216,7 @@
     public Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+        mTextPaint = new TextPaint();
 
         final Resources res = getResources();
         mTextPaint.density = res.getDisplayMetrics().density;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3e8df08..8ce5f08 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -668,11 +668,11 @@
         final Resources res = getResources();
         final CompatibilityInfo compat = res.getCompatibilityInfo();
 
-        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+        mTextPaint = new TextPaint();
         mTextPaint.density = res.getDisplayMetrics().density;
         mTextPaint.setCompatibilityScaling(compat.applicationScale);
 
-        mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mHighlightPaint = new Paint();
         mHighlightPaint.setCompatibilityScaling(compat.applicationScale);
 
         mMovement = getDefaultMovementMethod();
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a6c39e6..e347faa 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -307,7 +307,7 @@
     ResolveListAdapter createAdapter(Context context, Intent[] initialIntents,
             List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
         final ChooserListAdapter adapter = new ChooserListAdapter(context, initialIntents, rList,
-                launchedFromUid, filterLastUsed);
+                launchedFromUid, filterLastUsed, mCallerChooserTargets);
         if (DEBUG) Log.d(TAG, "Adapter created; querying services");
         queryTargetServices(adapter);
         return adapter;
@@ -315,45 +315,70 @@
 
     class ChooserTargetInfo implements TargetInfo {
         private final TargetInfo mSourceInfo;
+        private final ResolveInfo mBackupResolveInfo;
         private final ChooserTarget mChooserTarget;
         private final Drawable mDisplayIcon;
 
+        public ChooserTargetInfo(ChooserTarget target) {
+            this(null, target);
+        }
+
         public ChooserTargetInfo(TargetInfo sourceInfo, ChooserTarget chooserTarget) {
             mSourceInfo = sourceInfo;
             mChooserTarget = chooserTarget;
             mDisplayIcon = new BitmapDrawable(getResources(), chooserTarget.getIcon());
+
+            if (sourceInfo != null) {
+                mBackupResolveInfo = null;
+            } else {
+                mBackupResolveInfo = getPackageManager().resolveActivity(getResolvedIntent(), 0);
+            }
         }
 
         @Override
         public Intent getResolvedIntent() {
             final Intent targetIntent = mChooserTarget.getIntent();
-            return targetIntent != null ? targetIntent : mSourceInfo.getResolvedIntent();
+            if (targetIntent != null) {
+                return targetIntent;
+            } else if (mSourceInfo != null) {
+                return mSourceInfo.getResolvedIntent();
+            }
+            return getTargetIntent();
         }
 
         @Override
         public ComponentName getResolvedComponentName() {
-            return mSourceInfo.getResolvedComponentName();
+            if (mSourceInfo != null) {
+                return mSourceInfo.getResolvedComponentName();
+            } else if (mBackupResolveInfo != null) {
+                return new ComponentName(mBackupResolveInfo.activityInfo.packageName,
+                        mBackupResolveInfo.activityInfo.name);
+            }
+            return null;
+        }
+
+        private Intent getFillInIntent() {
+            return mSourceInfo != null ? mSourceInfo.getResolvedIntent() : getTargetIntent();
         }
 
         @Override
         public boolean start(Activity activity, Bundle options) {
-            return mChooserTarget.sendIntent(activity, mSourceInfo.getResolvedIntent());
+            return mChooserTarget.sendIntent(activity, getFillInIntent());
         }
 
         @Override
         public boolean startAsCaller(Activity activity, Bundle options, int userId) {
-            return mChooserTarget.sendIntentAsCaller(activity, mSourceInfo.getResolvedIntent(),
-                    userId);
+            return mChooserTarget.sendIntentAsCaller(activity, getFillInIntent(), userId);
         }
 
         @Override
         public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
-            return mChooserTarget.sendIntentAsUser(activity, mSourceInfo.getResolvedIntent(), user);
+            return mChooserTarget.sendIntentAsUser(activity, getFillInIntent(), user);
         }
 
         @Override
         public ResolveInfo getResolveInfo() {
-            return mSourceInfo.getResolveInfo();
+            return mSourceInfo != null ? mSourceInfo.getResolveInfo() : mBackupResolveInfo;
         }
 
         @Override
@@ -363,7 +388,7 @@
 
         @Override
         public CharSequence getExtendedInfo() {
-            return mSourceInfo.getExtendedInfo();
+            return mSourceInfo != null ? mSourceInfo.getExtendedInfo() : null;
         }
 
         @Override
@@ -374,10 +399,17 @@
 
     public class ChooserListAdapter extends ResolveListAdapter {
         private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
+        private final List<ChooserTargetInfo> mCallerTargets = new ArrayList<>();
 
         public ChooserListAdapter(Context context, Intent[] initialIntents, List<ResolveInfo> rList,
-                int launchedFromUid, boolean filterLastUsed) {
+                int launchedFromUid, boolean filterLastUsed, ChooserTarget[] callerChooserTargets) {
             super(context, initialIntents, rList, launchedFromUid, filterLastUsed);
+
+            if (callerChooserTargets != null) {
+                for (ChooserTarget target : callerChooserTargets) {
+                    mCallerTargets.add(new ChooserTargetInfo(target));
+                }
+            }
         }
 
         @Override
@@ -407,23 +439,25 @@
 
         @Override
         public int getCount() {
-            int count = super.getCount();
-            if (mServiceTargets != null) {
-                count += mServiceTargets.size();
-            }
-            return count;
+            return super.getCount() + mServiceTargets.size() + mCallerTargets.size();
         }
 
         @Override
         public TargetInfo getItem(int position) {
             int offset = 0;
-            if (mServiceTargets != null) {
-                final int serviceTargetCount = mServiceTargets.size();
-                if (position < serviceTargetCount) {
-                    return mServiceTargets.get(position);
-                }
-                offset += serviceTargetCount;
+
+            final int callerTargetCount = mCallerTargets.size();
+            if (position < callerTargetCount) {
+                return mCallerTargets.get(position);
             }
+            offset += callerTargetCount;
+
+            final int serviceTargetCount = mServiceTargets.size();
+            if (position - offset < serviceTargetCount) {
+                return mServiceTargets.get(position - offset);
+            }
+            offset += serviceTargetCount;
+
             return super.getItem(position - offset);
         }
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 7f51d92..8dd7836 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -376,6 +376,10 @@
         }
     }
 
+    public Intent getTargetIntent() {
+        return mIntent;
+    }
+
     private String getReferrerPackageName() {
         final Uri referrer = getReferrer();
         if (referrer != null && "android-app".equals(referrer.getScheme())) {
diff --git a/core/java/com/android/internal/midi/MidiFramer.java b/core/java/com/android/internal/midi/MidiFramer.java
index 53d71bb..1a7fa0b 100644
--- a/core/java/com/android/internal/midi/MidiFramer.java
+++ b/core/java/com/android/internal/midi/MidiFramer.java
@@ -17,6 +17,7 @@
 package com.android.internal.midi;
 
 import android.media.midi.MidiReceiver;
+import android.util.Log;
 
 import java.io.IOException;
 
@@ -38,6 +39,7 @@
     private int mCount;
     private int mRunningStatus;
     private int mNeeded;
+    private boolean mInSysEx;
 
     public MidiFramer(MidiReceiver receiver) {
         mReceiver = receiver;
@@ -52,12 +54,14 @@
     }
 
     /*
-     * @see android.midi.MidiReceiver#onPost(byte[], int, int, long)
+     * @see android.midi.MidiReceiver#onReceive(byte[], int, int, long)
      */
     @Override
     public void onReceive(byte[] data, int offset, int count, long timestamp)
             throws IOException {
         // Log.i(TAG, formatMidiData(data, offset, count));
+        int sysExStartOffset = (mInSysEx ? offset : -1);
+
         for (int i = 0; i < count; i++) {
             int b = data[offset] & 0xFF;
             if (b >= 0x80) { // status byte?
@@ -66,27 +70,50 @@
                     mCount = 1;
                     mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
                 } else if (b < 0xF8) { // system common?
-                    mBuffer[0] = (byte) b;
-                    mRunningStatus = 0;
-                    mCount = 1;
-                    mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
+                    if (b == 0xF0 /* SysEx Start */) {
+                        // Log.i(TAG, "SysEx Start");
+                        mInSysEx = true;
+                        sysExStartOffset = offset;
+                    } else if (b == 0xF7 /* SysEx End */) {
+                        // Log.i(TAG, "SysEx End");
+                        if (mInSysEx) {
+                            mReceiver.sendWithTimestamp(data, sysExStartOffset,
+                                offset - sysExStartOffset, timestamp);
+                            mInSysEx = false;
+                            sysExStartOffset = -1;
+                        }
+                    } else {
+                        mBuffer[0] = (byte) b;
+                        mRunningStatus = 0;
+                        mCount = 1;
+                        mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
+                    }
                 } else { // real-time?
                     // Single byte message interleaved with other data.
                     mReceiver.sendWithTimestamp(data, offset, 1, timestamp);
                 }
             } else { // data byte
-                mBuffer[mCount++] = (byte) b;
-                if (--mNeeded == 0) {
-                    if (mRunningStatus != 0) {
-                        mBuffer[0] = (byte) mRunningStatus;
+                // Save SysEx data for SysEx End marker or end of buffer.
+                if (!mInSysEx) {
+                    mBuffer[mCount++] = (byte) b;
+                    if (--mNeeded == 0) {
+                        if (mRunningStatus != 0) {
+                            mBuffer[0] = (byte) mRunningStatus;
+                        }
+                        mReceiver.sendWithTimestamp(mBuffer, 0, mCount, timestamp);
+                        mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
+                        mCount = 1;
                     }
-                    mReceiver.sendWithTimestamp(mBuffer, 0, mCount, timestamp);
-                    mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
-                    mCount = 1;
                 }
             }
             ++offset;
         }
+
+        // send any accumulatedSysEx data
+        if (sysExStartOffset >= 0) {
+            mReceiver.sendWithTimestamp(data, sysExStartOffset,
+                    offset - sysExStartOffset, timestamp);
+        }
     }
 
 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 2b0d244..9f99f62 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -24,7 +24,7 @@
 {
     void setIcon(int index, in StatusBarIcon icon);
     void removeIcon(int index);
-    void disable(int state);
+    void disable(int state1, int state2);
     void animateExpandNotificationsPanel();
     void animateExpandSettingsPanel();
     void animateCollapsePanels();
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 87e0603..663c838 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -28,6 +28,8 @@
     void collapsePanels();
     void disable(int what, IBinder token, String pkg);
     void disableForUser(int what, IBinder token, String pkg, int userId);
+    void disable2(int what, IBinder token, String pkg);
+    void disable2ForUser(int what, IBinder token, String pkg, int userId);
     void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
     void setIconVisibility(String slot, boolean visible);
     void removeIcon(String slot);
diff --git a/core/java/com/android/internal/util/ImageUtils.java b/core/java/com/android/internal/util/ImageUtils.java
index 7d56e9e..a0d0b20 100644
--- a/core/java/com/android/internal/util/ImageUtils.java
+++ b/core/java/com/android/internal/util/ImageUtils.java
@@ -66,7 +66,7 @@
                         COMPACT_BITMAP_SIZE, COMPACT_BITMAP_SIZE, Bitmap.Config.ARGB_8888
                 );
                 mTempCompactBitmapCanvas = new Canvas(mTempCompactBitmap);
-                mTempCompactBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+                mTempCompactBitmapPaint = new Paint();
                 mTempCompactBitmapPaint.setFilterBitmap(true);
             }
             mTempMatrix.reset();
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1096e34..3d23986 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -17,9 +17,11 @@
 package com.android.internal.widget;
 
 import android.Manifest;
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
+import android.bluetooth.BluetoothClass;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -142,11 +144,6 @@
     private DevicePolicyManager mDevicePolicyManager;
     private ILockSettings mLockSettingsService;
 
-    private final boolean mMultiUserMode;
-
-    // The current user is set by KeyguardViewMediator and shared by all LockPatternUtils.
-    private static volatile int sCurrentUserId = UserHandle.USER_NULL;
-
     public DevicePolicyManager getDevicePolicyManager() {
         if (mDevicePolicyManager == null) {
             mDevicePolicyManager =
@@ -171,12 +168,6 @@
     public LockPatternUtils(Context context) {
         mContext = context;
         mContentResolver = context.getContentResolver();
-
-        // If this is being called by the system or by an application like keyguard that
-        // has permision INTERACT_ACROSS_USERS, then LockPatternUtils will operate in multi-user
-        // mode where calls are for the current user rather than the user of the calling process.
-        mMultiUserMode = context.checkCallingOrSelfPermission(
-            Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED;
     }
 
     private ILockSettings getLockSettings() {
@@ -188,93 +179,55 @@
         return mLockSettingsService;
     }
 
-    public int getRequestedMinimumPasswordLength() {
-        return getDevicePolicyManager().getPasswordMinimumLength(null, getCurrentOrCallingUserId());
+    public int getRequestedMinimumPasswordLength(int userId) {
+        return getDevicePolicyManager().getPasswordMinimumLength(null, userId);
     }
 
     /**
      * Gets the device policy password mode. If the mode is non-specific, returns
      * MODE_PATTERN which allows the user to choose anything.
      */
-    public int getRequestedPasswordQuality() {
-        return getDevicePolicyManager().getPasswordQuality(null, getCurrentOrCallingUserId());
-    }
-
-    public int getRequestedPasswordHistoryLength() {
-        return getRequestedPasswordHistoryLength(getCurrentOrCallingUserId());
+    public int getRequestedPasswordQuality(int userId) {
+        return getDevicePolicyManager().getPasswordQuality(null, userId);
     }
 
     private int getRequestedPasswordHistoryLength(int userId) {
         return getDevicePolicyManager().getPasswordHistoryLength(null, userId);
     }
 
-    public int getRequestedPasswordMinimumLetters() {
-        return getDevicePolicyManager().getPasswordMinimumLetters(null,
-                getCurrentOrCallingUserId());
+    public int getRequestedPasswordMinimumLetters(int userId) {
+        return getDevicePolicyManager().getPasswordMinimumLetters(null, userId);
     }
 
-    public int getRequestedPasswordMinimumUpperCase() {
-        return getDevicePolicyManager().getPasswordMinimumUpperCase(null,
-                getCurrentOrCallingUserId());
+    public int getRequestedPasswordMinimumUpperCase(int userId) {
+        return getDevicePolicyManager().getPasswordMinimumUpperCase(null, userId);
     }
 
-    public int getRequestedPasswordMinimumLowerCase() {
-        return getDevicePolicyManager().getPasswordMinimumLowerCase(null,
-                getCurrentOrCallingUserId());
+    public int getRequestedPasswordMinimumLowerCase(int userId) {
+        return getDevicePolicyManager().getPasswordMinimumLowerCase(null, userId);
     }
 
-    public int getRequestedPasswordMinimumNumeric() {
-        return getDevicePolicyManager().getPasswordMinimumNumeric(null,
-                getCurrentOrCallingUserId());
+    public int getRequestedPasswordMinimumNumeric(int userId) {
+        return getDevicePolicyManager().getPasswordMinimumNumeric(null, userId);
     }
 
-    public int getRequestedPasswordMinimumSymbols() {
-        return getDevicePolicyManager().getPasswordMinimumSymbols(null,
-                getCurrentOrCallingUserId());
+    public int getRequestedPasswordMinimumSymbols(int userId) {
+        return getDevicePolicyManager().getPasswordMinimumSymbols(null, userId);
     }
 
-    public int getRequestedPasswordMinimumNonLetter() {
-        return getDevicePolicyManager().getPasswordMinimumNonLetter(null,
-                getCurrentOrCallingUserId());
+    public int getRequestedPasswordMinimumNonLetter(int userId) {
+        return getDevicePolicyManager().getPasswordMinimumNonLetter(null, userId);
     }
 
-    public void reportFailedPasswordAttempt() {
-        int userId = getCurrentOrCallingUserId();
+    public void reportFailedPasswordAttempt(int userId) {
         getDevicePolicyManager().reportFailedPasswordAttempt(userId);
         getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
         getTrustManager().reportRequireCredentialEntry(userId);
     }
 
-    public void reportSuccessfulPasswordAttempt() {
-        getDevicePolicyManager().reportSuccessfulPasswordAttempt(getCurrentOrCallingUserId());
-        getTrustManager().reportUnlockAttempt(true /* authenticated */,
-                getCurrentOrCallingUserId());
-    }
-
-    public void setCurrentUser(int userId) {
-        sCurrentUserId = userId;
-    }
-
-    public int getCurrentUser() {
-        if (sCurrentUserId != UserHandle.USER_NULL) {
-            // Someone is regularly updating using setCurrentUser() use that value.
-            return sCurrentUserId;
-        }
-        try {
-            return ActivityManagerNative.getDefault().getCurrentUser().id;
-        } catch (RemoteException re) {
-            return UserHandle.USER_OWNER;
-        }
-    }
-
-    private int getCurrentOrCallingUserId() {
-        if (mMultiUserMode) {
-            // TODO: This is a little inefficient. See if all users of this are able to
-            // handle USER_CURRENT and pass that instead.
-            return getCurrentUser();
-        } else {
-            return UserHandle.getCallingUserId();
-        }
+    public void reportSuccessfulPasswordAttempt(int userId) {
+        getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
+        getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
     }
 
     /**
@@ -286,8 +239,7 @@
      * @param challenge The challenge to verify against the pattern
      * @return the attestation that the challenge was verified, or null.
      */
-    public byte[] verifyPattern(List<LockPatternView.Cell> pattern, long challenge) {
-        final int userId = getCurrentOrCallingUserId();
+    public byte[] verifyPattern(List<LockPatternView.Cell> pattern, long challenge, int userId) {
         try {
             return getLockSettings().verifyPattern(patternToString(pattern), challenge, userId);
         } catch (RemoteException re) {
@@ -301,8 +253,7 @@
      * @param pattern The pattern to check.
      * @return Whether the pattern matches the stored one.
      */
-    public boolean checkPattern(List<LockPatternView.Cell> pattern) {
-        final int userId = getCurrentOrCallingUserId();
+    public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId) {
         try {
             return getLockSettings().checkPattern(patternToString(pattern), userId);
         } catch (RemoteException re) {
@@ -319,8 +270,7 @@
      * @param challenge The challenge to verify against the password
      * @return the attestation that the challenge was verified, or null.
      */
-    public byte[] verifyPassword(String password, long challenge) {
-        final int userId = getCurrentOrCallingUserId();
+    public byte[] verifyPassword(String password, long challenge, int userId) {
         try {
             return getLockSettings().verifyPassword(password, challenge, userId);
         } catch (RemoteException re) {
@@ -334,8 +284,7 @@
      * @param password The password to check.
      * @return Whether the password matches the stored one.
      */
-    public boolean checkPassword(String password) {
-        final int userId = getCurrentOrCallingUserId();
+    public boolean checkPassword(String password, int userId) {
         try {
             return getLockSettings().checkPassword(password, userId);
         } catch (RemoteException re) {
@@ -348,8 +297,7 @@
      * Note that this also clears vold's copy of the password.
      * @return Whether the vold password matches or not.
      */
-    public boolean checkVoldPassword() {
-        final int userId = getCurrentOrCallingUserId();
+    public boolean checkVoldPassword(int userId) {
         try {
             return getLockSettings().checkVoldPassword(userId);
         } catch (RemoteException re) {
@@ -364,8 +312,7 @@
      * @param password The password to check.
      * @return Whether the password matches any in the history.
      */
-    public boolean checkPasswordHistory(String password) {
-        int userId = getCurrentOrCallingUserId();
+    public boolean checkPasswordHistory(String password, int userId) {
         String passwordHashString = new String(
                 passwordToHash(password, userId), StandardCharsets.UTF_8);
         String passwordHistory = getString(PASSWORD_HISTORY_KEY, userId);
@@ -374,7 +321,7 @@
         }
         // Password History may be too long...
         int passwordHashLength = passwordHashString.length();
-        int passwordHistoryLength = getRequestedPasswordHistoryLength();
+        int passwordHistoryLength = getRequestedPasswordHistoryLength(userId);
         if(passwordHistoryLength == 0) {
             return false;
         }
@@ -416,16 +363,8 @@
      *
      * @return True if the user has ever chosen a pattern.
      */
-    public boolean isPatternEverChosen() {
-        return getBoolean(PATTERN_EVER_CHOSEN_KEY, false, getCurrentOrCallingUserId());
-    }
-
-    /**
-     * Used by device policy manager to validate the current password
-     * information it has.
-     */
-    public int getActivePasswordQuality() {
-        return getActivePasswordQuality(getCurrentOrCallingUserId());
+    public boolean isPatternEverChosen(int userId) {
+        return getBoolean(PATTERN_EVER_CHOSEN_KEY, false, userId);
     }
 
     /**
@@ -448,10 +387,6 @@
         return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
     }
 
-    public void clearLock() {
-        clearLock(getCurrentOrCallingUserId());
-    }
-
     /**
      * Clear any lock pattern or password.
      */
@@ -479,16 +414,6 @@
     }
 
     /**
-     * Disable showing lock screen at all when the DevicePolicyManager allows it.
-     * This is only meaningful if pattern, pin or password are not set.
-     *
-     * @param disable Disables lock screen when true
-     */
-    public void setLockScreenDisabled(boolean disable) {
-        setLockScreenDisabled(disable, getCurrentOrCallingUserId());
-    }
-
-    /**
      * Disable showing lock screen at all for a given user.
      * This is only meaningful if pattern, pin or password are not set.
      *
@@ -505,21 +430,16 @@
      *
      * @return true if lock screen is disabled
      */
-    public boolean isLockScreenDisabled() {
-        return !isSecure() &&
-                getBoolean(DISABLE_LOCKSCREEN_KEY, false, getCurrentOrCallingUserId());
+    public boolean isLockScreenDisabled(int userId) {
+        return !isSecure(userId) &&
+                getBoolean(DISABLE_LOCKSCREEN_KEY, false, userId);
     }
 
     /**
      * Save a lock pattern.
      * @param pattern The new pattern to save.
-     * @param savedPattern The previously saved pattern, or null if none
+     * @param userId the user whose pattern is to be saved.
      */
-    public void saveLockPattern(List<LockPatternView.Cell> pattern,
-            String savedPattern) {
-        this.saveLockPattern(pattern, savedPattern, getCurrentOrCallingUserId());
-    }
-
     public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) {
         this.saveLockPattern(pattern, null, userId);
     }
@@ -588,8 +508,7 @@
         updateCryptoUserInfo(userId);
     }
 
-    public void setOwnerInfoEnabled(boolean enabled) {
-        int userId = getCurrentOrCallingUserId();
+    public void setOwnerInfoEnabled(boolean enabled, int userId) {
         setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId);
         updateCryptoUserInfo(userId);
     }
@@ -598,11 +517,7 @@
         return getString(LOCK_SCREEN_OWNER_INFO, userId);
     }
 
-    public boolean isOwnerInfoEnabled() {
-        return isOwnerInfoEnabled(getCurrentOrCallingUserId());
-    }
-
-    private boolean isOwnerInfoEnabled(int userId) {
+    public boolean isOwnerInfoEnabled(int userId) {
         return getBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, false, userId);
     }
 
@@ -724,21 +639,10 @@
     /**
      * Save a lock password.  Does not ensure that the password is as good
      * as the requested mode, but will adjust the mode to be as good as the
-     * pattern.
+     * password.
      * @param password The password to save
      * @param savedPassword The previously saved lock password, or null if none
      * @param quality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
-     */
-    public void saveLockPassword(String password, String savedPassword, int quality) {
-        saveLockPassword(password, savedPassword, quality, getCurrentOrCallingUserId());
-    }
-
-    /**
-     * Save a lock password.  Does not ensure that the password is as good
-     * as the requested mode, but will adjust the mode to be as good as the
-     * pattern.
-     * @param password The password to save
-     * @param quality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
      * @param userHandle The userId of the user to change the password for
      */
     public void saveLockPassword(String password, String savedPassword, int quality,
@@ -865,16 +769,6 @@
     }
 
     /**
-     * Retrieves the quality mode we're in.
-     * {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
-     *
-     * @return stored password quality
-     */
-    public int getKeyguardStoredPasswordQuality() {
-        return getKeyguardStoredPasswordQuality(getCurrentOrCallingUserId());
-    }
-
-    /**
      * Retrieves the quality mode for {@param userHandle}.
      * {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
      *
@@ -997,13 +891,6 @@
     }
 
     /**
-     * @return Whether the lock screen is secured.
-     */
-    public boolean isSecure() {
-        return isSecure(getCurrentOrCallingUserId());
-    }
-
-    /**
      * @param userId the user for which to report the value
      * @return Whether the lock screen is secured.
      */
@@ -1012,13 +899,6 @@
         return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId);
     }
 
-    /**
-     * @return Whether the lock password is enabled
-     */
-    public boolean isLockPasswordEnabled() {
-        return isLockPasswordEnabled(getCurrentOrCallingUserId());
-    }
-
     public boolean isLockPasswordEnabled(int userId) {
         return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId);
     }
@@ -1035,10 +915,6 @@
     /**
      * @return Whether the lock pattern is enabled
      */
-    public boolean isLockPatternEnabled() {
-        return isLockPatternEnabled(getCurrentOrCallingUserId());
-    }
-
     public boolean isLockPatternEnabled(int userId) {
         return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId);
     }
@@ -1051,16 +927,14 @@
     /**
      * @return Whether the visible pattern is enabled.
      */
-    public boolean isVisiblePatternEnabled() {
-        return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, getCurrentOrCallingUserId());
+    public boolean isVisiblePatternEnabled(int userId) {
+        return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId);
     }
 
     /**
      * Set whether the visible pattern is enabled.
      */
-    public void setVisiblePatternEnabled(boolean enabled) {
-        int userId = getCurrentOrCallingUserId();
-
+    public void setVisiblePatternEnabled(boolean enabled, int userId) {
         setBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, enabled, userId);
 
         // Update for crypto if owner
@@ -1095,9 +969,9 @@
      * pattern until the deadline has passed.
      * @return the chosen deadline.
      */
-    public long setLockoutAttemptDeadline() {
+    public long setLockoutAttemptDeadline(int userId) {
         final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS;
-        setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, getCurrentOrCallingUserId());
+        setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, userId);
         return deadline;
     }
 
@@ -1106,8 +980,8 @@
      *   attempt to enter his/her lock pattern, or 0 if the user is welcome to
      *   enter a pattern.
      */
-    public long getLockoutAttemptDeadline() {
-        final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, getCurrentOrCallingUserId());
+    public long getLockoutAttemptDeadline(int userId) {
+        final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, userId);
         final long now = SystemClock.elapsedRealtime();
         if (deadline < now || deadline > (now + FAILED_ATTEMPT_TIMEOUT_MS)) {
             return 0L;
@@ -1166,21 +1040,12 @@
         }
     }
 
-    public void setPowerButtonInstantlyLocks(boolean enabled) {
-        setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, getCurrentOrCallingUserId());
+    public void setPowerButtonInstantlyLocks(boolean enabled, int userId) {
+        setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId);
     }
 
-    public boolean getPowerButtonInstantlyLocks() {
-        return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true,
-                getCurrentOrCallingUserId());
-    }
-
-    public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents) {
-        setEnabledTrustAgents(activeTrustAgents, getCurrentOrCallingUserId());
-    }
-
-    public List<ComponentName> getEnabledTrustAgents() {
-        return getEnabledTrustAgents(getCurrentOrCallingUserId());
+    public boolean getPowerButtonInstantlyLocks(int userId) {
+        return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId);
     }
 
     public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId) {
@@ -1192,7 +1057,7 @@
             sb.append(cn.flattenToShortString());
         }
         setString(ENABLED_TRUST_AGENTS, sb.toString(), userId);
-        getTrustManager().reportEnabledTrustAgentsChanged(getCurrentOrCallingUserId());
+        getTrustManager().reportEnabledTrustAgentsChanged(userId);
     }
 
     public List<ComponentName> getEnabledTrustAgents(int userId) {
@@ -1228,7 +1093,7 @@
     }
 
     public void setCredentialRequiredToDecrypt(boolean required) {
-        if (getCurrentUser() != UserHandle.USER_OWNER) {
+        if (ActivityManager.getCurrentUser() != UserHandle.USER_OWNER) {
             Log.w(TAG, "Only device owner may call setCredentialRequiredForDecrypt()");
             return;
         }
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index d86f71a..c384ef9 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -587,9 +587,8 @@
 static jboolean android_media_AudioRecord_setInputDevice(
         JNIEnv *env,  jobject thiz, jint device_id) {
 
-//    sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
-//    return lpRecorder->setInputDevice(device_id) == NO_ERROR;
-    return false;
+    sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
+    return lpRecorder->setInputDevice(device_id) == NO_ERROR;
 }
 
 // ----------------------------------------------------------------------------
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 773d42e..d4fb572 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -568,6 +568,29 @@
     return android_os_Debug_getPssPid(env, clazz, getpid(), NULL, NULL);
 }
 
+static long get_allocated_vmalloc_memory() {
+    char line[1024];
+    long size, vmalloc_allocated_size = 0;
+    FILE* fp = fopen("/proc/vmallocinfo", "r");
+    if (fp == NULL) {
+        return 0;
+    }
+    while (true) {
+        if (fgets(line, 1024, fp) == NULL) {
+            break;
+        }
+
+        if (!strstr(line, "ioremap")) {
+            // Ignore ioremap regions, since they don't actually consume memory
+            if (sscanf(line, "%*x-%*x %ld", &size) == 1) {
+                vmalloc_allocated_size += size;
+            }
+        }
+    }
+    fclose(fp);
+    return vmalloc_allocated_size;
+}
+
 enum {
     MEMINFO_TOTAL,
     MEMINFO_FREE,
@@ -588,7 +611,7 @@
 static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out)
 {
     char buffer[1024];
-    int numFound = 0;
+    size_t numFound = 0;
 
     if (out == NULL) {
         jniThrowNullPointerException(env, "out == null");
@@ -646,7 +669,7 @@
     long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
     char* p = buffer;
-    while (*p && numFound < 13) {
+    while (*p && numFound < (sizeof(tagsLen) / sizeof(tagsLen[0]))) {
         int i = 0;
         while (tags[i]) {
             if (strncmp(p, tags[i], tagsLen[i]) == 0) {
@@ -679,6 +702,9 @@
             mem[MEMINFO_ZRAM_TOTAL] = atoll(buffer)/1024;
         }
     }
+    // Recompute Vmalloc Used since the value in meminfo
+    // doesn't account for I/O remapping which doesn't use RAM.
+    mem[MEMINFO_VMALLOC_USED] = get_allocated_vmalloc_memory() / 1024;
 
     int maxNum = env->GetArrayLength(out);
     if (maxNum > MEMINFO_COUNT) {
@@ -693,6 +719,7 @@
     env->ReleaseLongArrayElements(out, outArray, 0);
 }
 
+
 static jint read_binder_stat(const char* stat)
 {
     FILE* fp = fopen(BINDER_STATS, "r");
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index cfbedda..fb82075 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -200,10 +200,8 @@
          * that can be made while an exception is pending, so we want to
          * get the VM ptr, throw the exception, and then detach the thread.
          */
-        JavaVM* vm = jnienv_to_javavm(env);
         env->Throw(excep);
-        vm->DetachCurrentThread();
-        sleep(60);
+        env->ExceptionDescribe();
         ALOGE("Forcefully exiting");
         exit(1);
     }
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 5cb8b2e..05bc125 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -40,6 +40,9 @@
 static jclass gLongClass;
 static jfieldID gLongValueID;
 
+static jclass gFloatClass;
+static jfieldID gFloatValueID;
+
 static jclass gStringClass;
 
 /*
@@ -66,6 +69,17 @@
 
 /*
  * In class android.util.EventLog:
+ *  static native int writeEvent(long tag, float value)
+ */
+static jint android_util_EventLog_writeEvent_Float(JNIEnv* env UNUSED,
+                                                  jobject clazz UNUSED,
+                                                  jint tag, jfloat value)
+{
+    return android_btWriteLog(tag, EVENT_TYPE_FLOAT, &value, sizeof(value));
+}
+
+/*
+ * In class android.util.EventLog:
  *  static native int writeEvent(int tag, String value)
  */
 static jint android_util_EventLog_writeEvent_String(JNIEnv* env,
@@ -128,6 +142,12 @@
             buf[pos++] = EVENT_TYPE_LONG;
             memcpy(&buf[pos], &longVal, sizeof(longVal));
             pos += sizeof(longVal);
+        } else if (env->IsInstanceOf(item, gFloatClass)) {
+            jfloat floatVal = env->GetFloatField(item, gFloatValueID);
+            if (pos + 1 + sizeof(floatVal) > max) break;
+            buf[pos++] = EVENT_TYPE_FLOAT;
+            memcpy(&buf[pos], &floatVal, sizeof(floatVal));
+            pos += sizeof(floatVal);
         } else {
             jniThrowException(env,
                     "java/lang/IllegalArgumentException",
@@ -233,6 +253,7 @@
     /* name, signature, funcPtr */
     { "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer },
     { "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long },
+    { "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float },
     { "writeEvent",
       "(ILjava/lang/String;)I",
       (void*) android_util_EventLog_writeEvent_String
@@ -251,6 +272,7 @@
     { "android/util/EventLog$Event", &gEventClass },
     { "java/lang/Integer", &gIntegerClass },
     { "java/lang/Long", &gLongClass },
+    { "java/lang/Float", &gFloatClass },
     { "java/lang/String", &gStringClass },
     { "java/util/Collection", &gCollectionClass },
 };
@@ -258,6 +280,7 @@
 static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
     { &gIntegerClass, "value", "I", &gIntegerValueID },
     { &gLongClass, "value", "J", &gLongValueID },
+    { &gFloatClass, "value", "F", &gFloatValueID },
 };
 
 static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 6bcc92e..a362684 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -112,8 +112,7 @@
         jlong rendererPtr, jlong functorPtr) {
     DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
     Functor* functor = reinterpret_cast<Functor*>(functorPtr);
-    android::uirenderer::Rect dirty;
-    renderer->callDrawGLFunction(functor, dirty);
+    renderer->callDrawGLFunction(functor);
 }
 
 // ----------------------------------------------------------------------------
@@ -212,12 +211,10 @@
 }
 
 static void android_view_DisplayListCanvas_drawRenderNode(JNIEnv* env,
-        jobject clazz, jlong rendererPtr, jlong renderNodePtr,
-        jint flags) {
+        jobject clazz, jlong rendererPtr, jlong renderNodePtr) {
     DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
-    android::uirenderer::Rect bounds;
-    renderer->drawRenderNode(renderNode, bounds, flags);
+    renderer->drawRenderNode(renderNode);
 }
 
 // ----------------------------------------------------------------------------
@@ -283,7 +280,7 @@
     { "nDrawCircle",        "(JJJJJ)V",        (void*) android_view_DisplayListCanvas_drawCircleProps },
 
     { "nFinishRecording",   "(J)J",            (void*) android_view_DisplayListCanvas_finishRecording },
-    { "nDrawRenderNode",    "(JJI)V",          (void*) android_view_DisplayListCanvas_drawRenderNode },
+    { "nDrawRenderNode",    "(JJ)V",           (void*) android_view_DisplayListCanvas_drawRenderNode },
 
     { "nCreateDisplayListCanvas", "()J",     (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 018c1a1..45c078d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1178,13 +1178,13 @@
     <permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"
         android:protectionLevel="system|signature" />
 
-    <!-- @SystemApi Allows an application to bind to InCallService implementations.
-         @hide -->
+    <!-- Must be required by a {@link android.telecom.InCallService},
+         to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_INCALL_SERVICE"
         android:protectionLevel="system|signature" />
 
-    <!-- @SystemApi Allows an application to bind to ConnectionService implementations.
-         @hide -->
+    <!-- Must be required by a {@link android.telecom.ConnectionService},
+         to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_CONNECTION_SERVICE"
         android:protectionLevel="system|signature" />
 
diff --git a/core/res/res/color/primary_text_activated_material_dark.xml b/core/res/res/color/primary_text_activated_material_dark.xml
deleted file mode 100644
index f1b742a..0000000
--- a/core/res/res/color/primary_text_activated_material_dark.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true"
-          android:color="@color/primary_text_default_material_light"/>
-    <item android:color="@color/primary_text_default_material_dark"/>
-</selector>
diff --git a/core/res/res/color/primary_text_activated_material_light.xml b/core/res/res/color/primary_text_activated_material_light.xml
deleted file mode 100644
index d92da63..0000000
--- a/core/res/res/color/primary_text_activated_material_light.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true"
-          android:color="@color/primary_text_default_material_dark"/>
-    <item android:color="@color/primary_text_default_material_light"/>
-</selector>
diff --git a/core/res/res/color/primary_text_inverse_when_activated_material.xml b/core/res/res/color/primary_text_inverse_when_activated_material.xml
new file mode 100644
index 0000000..0f7f9cdf
--- /dev/null
+++ b/core/res/res/color/primary_text_inverse_when_activated_material.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_enabled="false"
+        android:state_activated="true"
+        android:color="?attr/textColorPrimaryInverse"
+        android:alpha="?attr/disabledAlpha" />
+    <item
+        android:state_enabled="false"
+        android:color="?attr/textColorPrimary"
+        android:alpha="?attr/disabledAlpha" />
+    <item
+        android:state_activated="true"
+        android:color="?attr/textColorPrimaryInverse" />
+    <item
+        android:color="?attr/textColorPrimary" />
+</selector>
diff --git a/core/res/res/color/secondary_text_activated_material_dark.xml b/core/res/res/color/secondary_text_activated_material_dark.xml
deleted file mode 100644
index 7a8428a..0000000
--- a/core/res/res/color/secondary_text_activated_material_dark.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true"
-          android:color="@color/secondary_text_default_material_light"/>
-    <item android:color="@color/secondary_text_default_material_dark"/>
-</selector>
diff --git a/core/res/res/color/secondary_text_activated_material_light.xml b/core/res/res/color/secondary_text_activated_material_light.xml
deleted file mode 100644
index 36ff408..0000000
--- a/core/res/res/color/secondary_text_activated_material_light.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_activated="true"
-          android:color="@color/secondary_text_default_material_dark"/>
-    <item android:color="@color/secondary_text_default_material_light"/>
-</selector>
diff --git a/core/res/res/color/secondary_text_inverse_when_activated_material.xml b/core/res/res/color/secondary_text_inverse_when_activated_material.xml
new file mode 100644
index 0000000..5b259de
--- /dev/null
+++ b/core/res/res/color/secondary_text_inverse_when_activated_material.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:state_enabled="false"
+        android:state_activated="true"
+        android:color="?attr/textColorSecondaryInverse"
+        android:alpha="?attr/disabledAlpha" />
+    <item
+        android:state_enabled="false"
+        android:color="?attr/textColorSecondary"
+        android:alpha="?attr/disabledAlpha" />
+    <item
+        android:state_activated="true"
+        android:color="?attr/textColorSecondaryInverse" />
+    <item
+        android:color="?attr/textColorSecondary" />
+</selector>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 2718a27..6fc1a45 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Laat die program toe om WAP-boodskappe te ontvang en te verwerk. Hierdie toestemming sluit ook in dat boodskappe wat na jou toestel gestuur is, gemonitor of uitgevee kan word, sonder dat jy dit gesien het."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"haal lopende programme op"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Laat die program toe om inligting oor die huidig- en onlangslopende take op te haal. Dit kan moontlik die program toelaat om inligting oor watter programme op die toestel gebruik word, te ontdek."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Bestuur profiel- en toesteleienaars"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Laat programme toe om die profieleienaars en die toesteleienaar te stel."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"herrangskik lopende programme"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Laat die program toe om take na die voorgrond of agtergrond te skuif. Die program kan dit moontlik sonder jou insette doen."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktiveer motormodus"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 44b79c2..6a3d0c2 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"መተግበሪያው የWAP መልዕክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ፈቃድ የተላኩልዎን መልዕክቶች ለእርስዎ ሳያሳይዎ የመቆጣጠር ወይም የመሰረዝ ብቃትን ያጠቃልላል።"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"አሂድ መተግበሪያዎችን ሰርስረው ያውጡ"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"መተግበሪያው በአሁኑ ጊዜና በቅርቡ እየተካሄዱ ስላሉ ተግባሮችን መረጃ ሰርስሮ እንዲያወጣ ይፈቅድለታል። ይህ መተግበሪያው በመሳሪያው ላይ የትኛዎቹ መተግበሪያዎች ጥቅም ላይ ስለመዋላቸው መረጃ እንዲያገኝ ሊፈቅድለት ይችላል።"</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"የመገለጫ እና የመሣሪያ ባለቤቶችን ያስተዳድሩ"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"የመገለጫ ባለቤቶችን እና የመሣሪያውን ባለቤት መተግበሪያዎች እንዲያዋቅሩ ይፈቅዳል።"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"አሂድ ትግበራዎችን ድጋሚ ደርድር"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"መተግበሪያው ተግባሮችን ወደ ቅድመ ገጹ እና ወደ ዳራው እንዲያንቀሳቅስ ይፈቅድለታል። መተግበሪያው ይህንን ያላንተ ግብዓት ሊያደርግ ይችላል።"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"የመኪና ሁነታ አንቃ"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index c15116c..d60e0f0 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Разрешава на приложението да получава и обработва WAP съобщения. Това разрешение включва възможността да наблюдава или изтрива изпратените до вас, без да ви ги покаже."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"извличане на изпълняваните приложения"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Разрешава на приложението да извлича информация за задачите, изпълнявани понастоящем и неотдавна. Това може да му позволи да открива данни за това, кои приложения се използват на устройството."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Управление на собствениците на потребителските профили и на устройствата"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Разрешава на приложенията да задават собствениците на потребителските профили и собственика на устройствата."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"пренареждане на изпълняваните приложения"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Разрешава на приложението да прехвърля задачи на преден и на заден план. То може да направи това без вашето потвърждение."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"активиране на мото режима"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 64ae439..d61965a 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"অ্যাপ্লিকেশানটিকে WAP বার্তা প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"চলমান অ্যাপ্লিকেশান উদ্ধার করে"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"বর্তমানে ও সাম্প্রতিককালের সক্রিয় ক্রিয়াগুলি সম্বন্ধে তথ্য পুনরুদ্ধার করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ এছাড়া এটি ডিভাইসটিতে কোন অ্যাপ্লিকেশানগুলি ব্যবহৃত হচ্ছে তার বিষয়ে তথ্য খুঁজে বের করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করতে পারে৷"</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"প্রোফাইল এবং ডিভাইস মালিকদের পরিচালনা করুন"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"অ্যাপ্লিকেশানগুলিকে প্রোফাইলের মালিকদের এবং ডিভাইসের মালিককে সেট করার অনুমতি দেয়৷"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"চলমান অ্যাপ্লিকেশান পুনর্বিন্যাস করে"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"অ্যাপ্লিকেশানটিকে কার্যগুলিকে পুরোভাগে এবং পশ্চাদপটে সরানোর অনুমতি দেয়৷ অ্যাপ্লিকেশানটি আপনার ইনপুট ছাড়া এটি করতে পারে৷"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"গাড়ী মোড সক্ষম করে"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 319cf42..d1eda0e 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permet que l\'aplicació rebi i processi missatges WAP. Aquest permís inclou la capacitat de controlar o de suprimir missatges que s\'han enviat al teu dispositiu sense mostrar-te\'ls."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"recupera les aplicacions en execució"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permet que l\'aplicació recuperi informació sobre les tasques que s\'executen actualment i les que s\'han executat recentment. Aquesta acció pot permetre que l\'aplicació descobreixi informació sobre les aplicacions que s\'utilitzen al dispositiu."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gestionar els propietaris del perfil i del dispositiu"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permet que les aplicacions defineixin els propietaris del perfil i del dispositiu."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"canvia l\'ordre de les aplicacions en execució"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permet que l\'aplicació desplaci tasques en primer o segon pla. L\'aplicació pot fer-ho sense que tu ho indiquis."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"activar el mode de cotxe"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index e987685..ed5b413 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -276,10 +276,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Umožňuje aplikaci přijmout a zpracovat zprávy WAP. Toto oprávnění umožňuje sledovat přijaté zprávy nebo je smazat, aniž by se vám zobrazily."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"načtení spuštěných aplikací"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Umožňuje aplikaci získat informace o aktuálně a naposledy spuštěných úlohách. Aplikace s tímto oprávněním může odhalit informace o aplikacích, které se v zařízení používají."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Správa vlastníků profilu a zařízení"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Umožňuje aplikacím nastavit vlastníky profilu a vlastníka zařízení."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"změna uspořádání spuštěných aplikací"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Umožňuje aplikaci přesunout úlohy na popředí nebo pozadí. Aplikace tak může činit bez vašeho zásahu."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivovat režim V autě"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ce899e9f..9918b08 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Tillader, at appen kan modtage og behandle WAP-beskeder. Denne tilladelse omfatter muligheden for at overvåge eller slette de beskeder, der sendes til dig, uden at vise dem til dig."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"hente kørende apps"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Tillader, at appen kan hente oplysninger om nuværende og seneste opgaver. Med denne tilladelse kan appen finde oplysninger om, hvilke applikationer der bruges på enheden."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Administrer profil- og enhedsejere"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Tillader, at apps konfigurerer profilejerne og enhedens ejer."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"omorganisere kørende apps"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Tillader, at appen kan flytte opgaver til forgrunden og baggrunden. Appen kan gøre dette uden din bekræftelse."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivere biltilstand"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index e914408..cea19ac 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Ermöglicht der App, WAP-Nachrichten zu empfangen und zu verarbeiten. Mit der Berechtigung können Nachrichten, die an Sie gesendet wurden, überwacht und gelöscht werden, bevor sie Ihnen angezeigt werden."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"Aktive Apps abrufen"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Ermöglicht der App, Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Damit kann die App möglicherweise ermitteln, welche Apps auf Ihrem Gerät zum Einsatz kommen."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profilinhaber und Geräteeigentümer verwalten"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Ermöglicht Apps das Einrichten der Profilinhaber und des Geräteeigentümers"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Aktive Apps neu ordnen"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ermöglicht der App, Aufgaben in den Vorder- und Hintergrund zu verschieben, ohne dass dazu ein Eingreifen Ihrerseits notwendig ist."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"Automodus aktivieren"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index c72d9c9..0f9ada3 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Επιτρέπει στην εφαρμογή τη λήψη και την επεξεργασία μηνυμάτων WAP. Αυτό σημαίνει ότι η εφαρμογή θα μπορούσε να παρακολουθήσει ή να διαγράψει τα μηνύματα που αποστέλλονται στη συσκευή σας χωρίς αυτά να εμφανιστούν σε εσάς."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ανάκτηση εκτελούμενων εφαρμογών"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Επιτρέπει στην εφαρμογή την ανάκτηση πληροφοριών σχετικά με τρέχουσες και πρόσφατα εκτελούμενες εργασίες. Αυτό μπορεί να δίνει τη δυνατότητα στην εφαρμογή να ανακαλύπτει πληροφορίες σχετικά με το ποιες εφαρμογές χρησιμοποιούνται στη συσκευή."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Διαχείριση προφίλ και κατόχων συσκευής"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Επιτρέπει σε εφαρμογές να ορίζουν τους κατόχους προφίλ και τον κάτοχο της συσκευής."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"αναδιάταξη εκτελούμενων εφαρμογών"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Επιτρέπει στην εφαρμογή τη μετακίνηση εργασιών στο προσκήνιο και το παρασκήνιο. Η εφαρμογή μπορεί να το κάνει αυτό χωρίς να καταχωρίσετε δεδομένα εισόδου."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ενεργοποίηση λειτουργίας αυτοκινήτου"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a215317..5a04b8b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite que la aplicación reciba y procese mensajes WAP, lo que significa que podría controlar o eliminar mensajes enviados al usuario sin mostrártelos."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"recuperar aplicaciones en ejecución"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite que la aplicación recupere información sobre las tareas que se estén ejecutando en ese momento o que se hayan ejecutado recientemente. La aplicación puede utilizar este permiso para descubrir cuáles son las aplicaciones que se utilizan en el dispositivo."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Administrar perfiles de propietarios y propietario del dispositivo"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permite que las aplicaciones configuren los perfiles de propietarios y el propietario del dispositivo."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reorganizar aplicaciones en ejecución"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que la aplicación mueva tareas a segundo o a primer plano. La aplicación puede utilizar este permiso para realizar estos movimientos sin indicártelo."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"activar el modo de auto"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index e096e1a..f05757d 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite que la aplicación reciba y procese mensajes WAP, lo que significa que podría utilizar este permiso para controlar o eliminar mensajes enviados al usuario sin mostrárselos."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"recuperar aplicaciones en ejecución"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite que aplicación recupere información sobre tareas que se están ejecutando en ese momento o que se han ejecutado recientemente. La aplicación puede utilizar este permiso para descubrir cuáles son las aplicaciones que se utilizan en el dispositivo."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Administrar propietarios del perfil y del dispositivo"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permite que las aplicaciones establezcan los propietarios del perfil y del dispositivo."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reorganizar aplicaciones en ejecución"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que la aplicación mueva tareas a segundo o a primer plano. La aplicación puede utilizar este permiso para realizar estos movimientos sin que se lo indique el usuario."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"habilitar modo coche"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 6304ef3..9ee98df 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Võimaldab rakendusel vastu võtta ja töödelda WAP-sõnumeid. See luba hõlmab võimet jälgida või kustutada teile saadetud sõnumeid neid teile näitamata."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"Käitatud rakenduste toomine"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Võimaldab rakendusel tuua teavet praegu ja hiljuti käitatud ülesannete kohta. See võib lubada rakendusel avastada teavet selle kohta, milliseid rakendusi seadmes kasutatakse."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profiili- ja seadmeomanike haldamine"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Võimaldab rakendustel määrata profiiliomanikud ja seadmeomaniku."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"käitatud rakenduste ümberjärjestamine"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Võimaldab rakendusel teisaldada ülesanded esiplaanile ja taustale. Rakendus võib seda teha teie sisendita."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"autorežiimi lubamine"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index c017f54..31371d0 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP mezuak jasotzeko eta prozesatzeko baimena ematen die aplikazioei. Horrela, aplikazioak, besteak beste, gailura bidalitako mezuak kontrola eta ezaba ditzake zuri erakutsi gabe."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"Eskuratu abian diren aplikazioak"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Unean edo duela gutxi exekutatutako zereginei buruzko informazioa lortzeko baimena ematen die aplikazioei. Horrela, aplikazioak gailuan erabiltzen ari diren aplikazioei buruzko informazioa ezagut dezake."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Kudeatu profilen eta gailuen jabeak"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Profilaren eta gailuaren jabeak zehazteko baimena ematen die aplikazioei"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Ordenatu abian diren aplikazioak"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Zereginak aurreko eta atzeko planora eramateko baimena ematen die aplikazioei. Aplikazioak zuk ezer egin gabe egin dezake hori."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"gaitu auto modua"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5e2123f..cb0f601 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Antaa sovelluksen vastaanottaa ja käsitellä WAP-viestejä. Sovellus voi valvoa tai poistaa laitteeseesi lähetettyjä viestejä näyttämättä niitä sinulle."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"käynnissä olevien sovellusten noutaminen"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Antaa sovelluksen noutaa tietoja käynnissä olevista ja äskettäin suoritetuista tehtävistä. Sovellus voi saada tietoja laitteella käytetyistä sovelluksista."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Hallinnoi laitteen ja profiilien omistajia"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Sallii sovelluksien määrittää laitteen ja profiilien omistajat."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"käynnissä olevien sovellusten järjesteleminen"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Antaa sovelluksen siirtää tehtäviä etualalle ja taustalle. Sovellus ei tarvitse toimiin käyttäjän lupaa."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ota autotila käyttöön"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 573ef2a..9bed850 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permet à l\'application de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"récupérer les données des applications en cours d\'exécution"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permet à l\'application de récupérer des données sur des tâches en cours d\'exécution et récemment exécutées. L\'application est ainsi susceptible d\'obtenir des données concernant les applications utilisées sur l\'appareil."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gérer les propriétaires des profils et de l\'appareil"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Autoriser les applications à définir les propriétaires des profils et celui de l\'appareil"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"réorganiser les applications en cours d\'exécution"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permet à l\'application de déplacer les tâches au premier plan et en arrière-plan. L\'application peut procéder à ces opérations sans votre intervention."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"activer le mode voiture"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f01dbcc..b46f4d5 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permet à l\'application de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"récupérer les applications en cours d\'exécution"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permet à l\'application de récupérer des informations sur des tâches en cours d\'exécution et récemment exécutées. L\'application est ainsi susceptible d\'obtenir des informations sur les applications utilisées sur l\'appareil."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gérer les propriétaires des profils et de l\'appareil"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Autoriser les applications à définir les propriétaires des profils et celui de l\'appareil"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"réorganiser les applications en cours d\'exécution"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permet à l\'application de déplacer les tâches au premier plan et en arrière-plan. L\'application peut procéder à ces opérations sans votre intervention."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"activer le mode voiture"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 58a036c..ca089bb 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite á aplicación recibir e procesar mensaxes WAP. Este permiso inclúe a capacidade de supervisar ou eliminar mensaxes enviadas a ti sen mostrarchas."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"recuperar aplicacións en execución"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite á aplicación recuperar información acerca de tarefas que se están executando actualmente ou que se executaron recentemente. É posible que esta acción permita á aplicación descubrir información acerca de que aplicacións se utilizan no dispositivo."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Xestionar os propietarios do perfil e do dispositivo"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permite ás aplicacións establecer os propietarios do perfil e o propietario do dispositivo."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar as aplicacións en execución"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite á aplicación mover tarefas ao primeiro e segundo plano. É posible que a aplicación leve a cabo esta acción sen a túa intervención."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"activar o modo coche"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index aa5bc87..9f90ed6 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ऐप्स  को WAP संदेशों को प्राप्‍त और संसाधित करने देता है. इस अनुमति में आपको भेजे गए संदेशों की निगरानी आपको दिखाए बिना करने और हटाने की क्षमता शामिल है."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"चल रहे ऐप्स पुनर्प्राप्त करें"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"ऐप्स  को वर्तमान में और हाल ही में चल रहे कार्यों के बारे में जानकारी को पुन: प्राप्‍त करने देता है. इससे ऐप्स  डिवाइस पर उपयोग किए गए ऐप्स  के बारे में जानकारी खोज सकता है."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"प्रोफ़ाइल और डिवाइस स्‍वामियों को प्रबंधित करें"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ऐप्‍स को प्रोफ़ाइल स्‍वामी और डिवाइस स्‍वामी सेट करने दें."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे ऐप्स पुन: क्रमित करें"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ऐप्स  को कार्यों को अग्रभूमि और पृष्‍ठभूमि पर ले जाने देता है. ऐप्स  आपके इनपुट के बिना यह कर सकता है."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सक्षम करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index adce98d..a340ac6 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -275,10 +275,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Aplikaciji omogućuje primanje i obradu WAP poruka. Ta dozvola uključuje mogućnost nadziranja ili brisanja vama poslanih poruka, a da vam ih ne prikaže."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"dohvaćanje pokrenutih aplikacija"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Aplikaciji omogućuje dohvaćanje informacija o trenutačnim i nedavnim tekućim zadacima. To aplikaciji može omogućiti otkrivanje informacija o tome koje se aplikacije upotrebljavaju na uređaju."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Upravljanje vlasnicima profila i uređaja"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Omogućuje aplikaciji postavljanje vlasnika profila i vlasnika uređaja."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"promjena redoslijeda pokrenutih aplikacija"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Aplikaciji omogućuje premještanje zadataka u prednji plan ili pozadinu. Aplikacija to može napraviti bez vašeg naloga."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"omogućavanje načina rada za automobil"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 2e54743f..f1db0a8 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Lehetővé teszi az alkalmazás számára, hogy WAP-üzeneteket fogadjon és dolgozzon fel. Ez azt is jelenti, hogy az alkalmazás megfigyelheti vagy törölheti a beérkező üzeneteket anélkül, hogy Ön látná azokat."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"futó alkalmazások lekérése"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Lehetővé teszi az alkalmazás számára a jelenleg futó és nemrég befejezett feladatokkal kapcsolatos információk lekérését. Ezáltal az alkalmazás engedélyt kap az eszközön használt alkalmazásokkal kapcsolatos információk felderítésére."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profil- és eszköztulajdonosok kezelése"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Lehetővé teszi, hogy az alkalmazások beállítsák a profil- és az eszköztulajdonosokat."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"futó alkalmazások átrendezése"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Lehetővé teszi az alkalmazás számára, hogy feladatokat helyezzen át az előtérből a háttérbe és fordítva. Az alkalmazás ezt az Ön jóváhagyása nélkül is megteheti."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"gépkocsi üzemmód bekapcsolása"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 62517a5..3807578 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Թույլ է տալիս հավելվածին ստանալ և գործարկել WAP հաղորդագրությունները: Այս թույլտվությունը ներառում է ձեզ ուղարկված հաղորդագրությունները հետևելու կամ ջնջելու կարողությունը` առանց ձեր տեսնելու:"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"առբերել աշխատող հավելվածները"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Թույլ է տալիս հավելվածին առբերել մանրամասն տեղեկություններ առկա և վերջերս աշխատող առաջադրանքների մասին: Սա կարող է թույլ տալ հավելվածին հայտնաբերել անձնական տեղեկություններ այլ հավելվածների վերաբերյալ:"</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Պրոֆիլների և սարքի սեփականատերերի կառավարում"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Թույլ է տալիս հավելվածներին սահմանել պրոֆիլների սեփականատերերին և սարքի սեփականատիրոջը:"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"վերադասավորել աշխատող հավելվածները"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Թույլ է տալիս հավելվածին փոխանցել առաջադրանքները առջևք և հետնաշերտ: Հավելվածը կարող է սա անել առանց ձեր ներածման:"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"միացնել մեքենայի ռեժիմը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index a184cb3..59f48cc 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Memungkinkan aplikasi menerima dan memproses pesan WAP. Izin ini mencakup kemampuan untuk memantau atau menghapus pesan yang dikirim kepada Anda tanpa menunjukkannya kepada Anda."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"mengambil apl yang berjalan"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Memungkinkan aplikasi mengambil informasi tentang tugas yang dijalankan saat ini dan baru-baru ini. Izin ini memungkinkan aplikasi menemukan informasi tentang aplikasi mana yang digunakan pada perangkat."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Mengelola pemilik profil dan perangkat"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Mengizinkan aplikasi menyetel pemilik profil dan pemilik perangkat"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"menyusun ulang apl yang berjalan"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Memungkinkan aplikasi memindah tugas ke latar depan dan latar belakang. Aplikasi dapat melakukannya tanpa masukan dari Anda."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktifkan mode mobil"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index a59e43e..a234eb4 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Leyfir forriti að taka á móti og vinna úr WAP-skilaboðum. Þessi heimild felur í sér möguleikann á að fylgjast með eða eyða skilaboðum sem þér eru send án þess að birta þér þau."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"sækja forrit í gangi"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Leyfir forriti að sækja upplýsingar um opin forrit og forrit sem nýlega hafa verið opin. Þetta getur gert forritinu kleift að nálgast upplýsingar um forritin sem notuð eru í tækinu."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Stjórna eigendum sniða og tækis"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Leyfir forritum að stilla eigendur sniða og eiganda tækisins."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"endurraða forritum í gangi"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Leyfir forriti að færa verk á milli forgrunns og bakgrunns. Forritið getur gert þetta án inngrips frá þér."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"kveikja á bílastillingu"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 324c391..a3ae79d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Consente all\'applicazione di ricevere ed elaborare messaggi WAP. Questa autorizzazione include la facoltà di monitorare o eliminare i messaggi che ti vengono inviati senza mostrarteli."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"recupero applicazioni in esecuzione"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Consente all\'applicazione di recuperare informazioni sulle attività attualmente e recentemente in esecuzione. Ciò potrebbe consentire all\'applicazione di scoprire informazioni sulle applicazioni in uso sul dispositivo."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gestione dei proprietari di profili e dispositivi"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Consente alle app di impostare i proprietari dei profili e dei dispositivi."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"riordinamento applicazioni in esecuzione"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Consente all\'applicazione di spostare attività in primo piano e in background. L\'applicazione potrebbe farlo senza un tuo comando."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"abilitazione modalità auto"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index bc9c128..9c77257 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAPメッセージの受信と処理をアプリに許可します。これにより、アプリが端末に届いたメッセージを表示することなく監視または削除できるようになります。"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"実行中のアプリの取得"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"現在実行中または最近実行したタスクに関する情報の取得をアプリに許可します。これにより、その端末でどのアプリを使用しているかをアプリから識別できるようになる可能性があります。"</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"プロフィールの所有者と端末の所有者の管理"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"プロフィールの所有者と端末の所有者の設定をアプリに許可します。"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"実行中のアプリの順序変更"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"タスクをフォアグラウンドやバックグラウンドに移動することをアプリに許可します。これにより、アプリがユーザーからの入力なしでこの処理を実行する可能性があります。"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"運転モードの有効化"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 827512b..fc88343 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Қолданбаға WAP хабарларын алу және өңдеу мүмкіндігін береді. Бұл қолданба құрылғыңызға жіберілген хабарларды сізге көрсетпестен қабылдай және жоя алады дегенді білдіреді."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"жұмыс істеп жатқан қолданбаларды шығарып алу"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Қолданбаларға ағымдағы және соңғы тапсырмалар туралы ақпарат алу мүмкіндігін береді. Бұл қолданбаға құрылғы қолданатын басқа қолданбалар туралы деректері анықтау мүмкіндігін беруі ықтимал."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Профиль және құрылғы иелерін басқару"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Қолданбаларға профиль иелері мен құрылғы иесін орнатуға мүмкіндік береді."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"жұмыс істеп жатқан қолданбалардың ретін өзгерту"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Қолданбаға тапсырмаларды алғы немесе артқы шепке жылжыту мүмкіндігін береді. Қолданба бұны сіздің қатысуыңызсыз жасауы мүмкін."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"автокөлік режимін қосу"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index b4d6319..eeee275 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ឲ្យ​កម្មវិធី​ទទួល និង​ដំណើរការ​សារ WAP ។ សិទ្ធិ​នេះ​​មានលទ្ធភាព​តាមដាន ឬ​លុប​សារ​ដែល​បាន​ផ្ញើ​ឲ្យ​អ្នក​ដោយ​មិន​បង្ហា​ញ។"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ទៅ​យក​កម្មវិធី​កំពុង​ដំណើរការ"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"ឲ្យ​កម្មវិធី​ទៅ​យក​ព័ត៌មាន​លម្អិត​អំពី​កិច្ចការ​ដែល​កំពុង​ដំណើរការ​បច្ចុប្បន្ន។ វា​អាច​ឲ្យ​កម្មវិធី​រកមើល​ព័ត៌មាន​ថា​តើ​កម្មវិធី​ណាមួយ​ត្រូវ​បាន​ប្រើ​លើ​ឧបករណ៍។"</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"គ្រប់គ្រងម្ចាស់ឧបករណ៍ និងប្រវត្តិរូប"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"អនុញ្ញាតឲ្យកម្មវិធីកំណត់ម្ចាស់ប្រវត្តិរូប និងម្ចាស់ឧបករណ៍។"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"តម្រៀប​កម្មវិធី​កំពុង​ដំណើរការ​ឡើងវិញ"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ឲ្យ​កម្មវិធី​ផ្លាស់ទី​ភារកិច្ច​​ទៅ​ផ្ទៃ​ខាង​មុខ។​ កម្មវិធី​អាច​ធ្វើ​វា​ដោយ​គ្មាន​ការ​បញ្ចូល​របស់​អ្នក។"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"បើក​របៀប​រថយន្ត"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 6948575..125625f 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಮತ್ತು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು, ನಿಮಗೆ ಕಳುಹಿಸಲಾಗಿರುವ ಸಂದೇಶಗಳನ್ನು ನಿಮಗೆ ತೋರಿಸದೆಯೇ, ಅವುಗಳನ್ನು ಮಾನಿಟರ್ ಮಾಡುವ ಅಥವಾ ಅಳಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ರನ್‌ ಆಗುತ್ತಿರುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹಿಂಪಡೆಯಿರಿ"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"ಪ್ರಸ್ತುತವಿರುವ ಮತ್ತು ಇತ್ತೀಚಿಗೆ ಚಾಲ್ತಿಯಾಗಿರುವ ಕಾರ್ಯಗಳ ಕುರಿತ ಮಾಹಿತಿಯನ್ನು ಮರುಪಡೆದುಕೊಳ್ಳಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದು ಸಾಧನದಲ್ಲಿ ಯಾವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬಳಸಲಾಗಿದೆ ಎಂಬುದರ ಕುರಿತ ಮಾಹಿತಿಯನ್ನು ಅನ್ವೇಷಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"ಪ್ರೊಫೈಲ್ ಮತ್ತು ಸಾಧನ ಮಾಲೀಕರನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ಪ್ರೊಫೈಲ್ ಮಾಲೀಕರು ಮತ್ತು ಸಾಧನ ಮಾಲೀಕರನ್ನು ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"ರನ್‌ ಆಗುತ್ತಿರುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಮರುಕ್ರಮಗೊಳಿಸಿ"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ಮುನ್ನೆಲೆ ಮತ್ತು ಹಿನ್ನಲೆಗೆ ಕಾರ್ಯಗಳನ್ನು ಸರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ನಿಮ್ಮ ಇನ್‍‍ಪುಟ್ ಇಲ್ಲದೆಯೇ, ಅಪ್ಲಿಕೇಶನ್ ಈ ಕಾರ್ಯವನ್ನು ಮಾಡಬಹುದು."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ಕಾರ್ ಮೋಡ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 63c1840..4fe2cfb 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -386,10 +386,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Колдонмого WAP билдирүүлөрүн кабыл алууга жана аларды иштетип чыгууга уруксат берет. Бул, колдонмо сизге билгизбестен түзмөгүңүзгө жөнөтүлгөн билдирүүлөрдү мониторлой же жок кыла алат дегенди билдирет."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"иштеп жаткан колдонмолорду түшүрүп алуу"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Колдонмого учурдагы жана акыркы убакытта пайдаланылган колдонмолор тууралуу  маалымат алууга уруксат берет. Бул колдонмого түзмөктө кандай колдонмолор колдонулаарын билип алууга жол бериши мүмкүн."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Профилди жана түзмөк ээлерин башкаруу"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Колдонмолорго профиль ээлерин жана түзмөк ээсин орнотуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"иштеп жаткан колдонмолорду иреттештирүү"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Колдонмо процесстерди фонго же алдыңкы планга жылдыруу уруксатын алат. Колдонмо муну сиздин ырастооңузсуз кыла алат."</string>
     <!-- no translation found for permlab_enableCarMode (5684504058192921098) -->
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 014a659..0453de9 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"ອະນຸຍາດໃຫ້ແອັບຯຮັບ ແລະປະມວນຜົນຂໍ້ຄວາມ WAP. ການອະນຸຍາດນີ້ຮວມເຖິງຄວາມສາມາດໃນການກວດເບິ່ງ ແລະລຶບຂໍ້ຄວາມທີ່ສົ່ງແລ້ວ ໂດຍບໍ່ຕ້ອງສະແດງໃຫ້ທ່ານເຫັນ."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ດຶງແອັບຯທີ່ເຮັດວຽກຢູ່ມາ"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"ອະນຸຍາດໃຫ້ແອັບຯດຶງຂໍ້ມູນກ່ຽວກັບການເຮັດວຽກໃນປັດຈຸບັນ ແລະຫາກໍຜ່ານມາ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຄົ້ນພົບຂໍ້ມູນ ກ່ຽວກັບແອັບພລິເຄຊັນທີ່ໃຊ້ຢູ່ໃນອຸປະກອນໄດ້."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"ຈັດ​ການ​ເຈົ້າ​ຂອງ​ໂປ​ຣ​ໄຟ​ລ໌ ແລະ​ອຸ​ປະ​ກອນ"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບ​ຕັ້ງ​ເຈົ້າ​ຂອງ​ໂປ​ຣ​ໄຟ​ລ໌ ແລະ​ເຈົ້າ​ຂອງ​ອຸ​ປະ​ກອນ."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"ຮຽງລຳດັບແອັບຯທີ່ກຳລັງເຮັດວຽກຄືນໃໝ່"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ອະນຸຍາດໃຫ້ແອັບຯຍ້າຍການເຮັດວຽກໄປໃສ່ດ້ານໜ້າ ແລະພື້ນຫຼັງໄດ້. ແອັບຯອາດຈະດຳເນີນການໂດຍບໍ່ຕ້ອງໃຫ້ທ່ານບອກ."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ເປີດນຳໃຊ້ໂຫມດຂັບລົດ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index cca0c33..30c1610 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -276,10 +276,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Leidžiama programai gauti ir apdoroti WAP pranešimus. Šis leidimas apima galimybę stebėti ar ištrinti jums siunčiamus pranešimus jums jų neparodžius."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"nuskaityti vykdomas programas"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Leidžiama programai nuskaityti informaciją apie šiuo ir pastaruoju metu vykdomas užduotis. Taip programa gali atrasti informacijos, kokios programos naudojamos įrenginyje."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Tvarkyti profilio ir įrenginio savininkus"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Leisti programai nustatyti profilio savininkus ir įrenginio savininką."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"pertvarkyti vykdomas programas"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Leidžiama programai perkelti užduotis į priekinį planą ir foną. Programa gali tai daryti be jūsų įsikišimo."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"įgalinti automobilio režimą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 10aa4d0..bdefa64 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -275,10 +275,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Ļauj lietotnei saņemt un apstrādāt WAP ziņojumus. Šī atļauja ietver iespēju pārraudzīt vai dzēst jums nosūtītos ziņojumus, neparādot tos jums."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"izgūt izmantotās lietotnes"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Ļauj lietotnei izgūt informāciju par pašreiz un nesen darbinātajiem uzdevumiem. Tādējādi lietotne var atklāt informāciju par ierīcē izmantotajām lietojumprogrammām."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profilu un ierīces īpašnieku pārvaldība"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Atļaut lietotnēm iestatīt profilu īpašniekus un ierīces īpašnieku."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"pārkārtot izmantotās lietotnes"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ļauj lietotnei pārvietot uzdevumus priekšplānā un fonā. Lietotne var to izdarīt bez jūsu apstiprinājuma."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"iespējot automobiļa režīmu"</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 4845a3f..3ce3cf0 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Овозможува апликацијата да прима и да обработува WAP пораки. Оваа дозвола ја опфаќа способноста за следење или за бришење пораки испратени до вашиот уред без да ви ги прикаже вам."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"обнови активни апликации"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Овозможува апликацијата да поврати информации за тековно и до неодамна активни задачи. Ова може да овозможи апликацијата да открие информации за тоа кои апликации се користат на уредот."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Управувај сопственици на профил и уред"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Дозволува апликациите до постават сопственици на профили и сопственик на уредот."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"преуреди активни апликации"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Овозможува апликацијата да преместува задачи во преден план и во заднина. Апликацијата може да го прави тоа без вашиот придонес."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"овозможи режим на автомобил"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index f7b9207..0631b73 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP സന്ദേശങ്ങൾ നേടാനും പ്രോസസ്സുചെയ്യാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങൾക്ക് അയയ്‌ക്കുന്ന സന്ദേശങ്ങൾ നിങ്ങൾക്ക് ദൃശ്യമാക്കാതെ തന്നെ നിരീക്ഷിക്കാനോ ഇല്ലാതാക്കാനോ ഉള്ള കഴിവ് ഈ അനുമതികളിൽ ഉൾപ്പെടുന്നു."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"പ്രവർത്തിക്കുന്ന അപ്ലിക്കേഷനുകൾ വീണ്ടെടുക്കുക"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"നിലവിലും സമീപകാലത്തും പ്രവർത്തിക്കുന്ന ടാസ്‌ക്കുകളെക്കുറിച്ചുള്ള വവിവരങ്ങൾ വീണ്ടെടുക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് ഉപകരണത്തിൽ ഉപയോഗിച്ച അപ്ലിക്കേഷനുകളെക്കുറിച്ചുള്ള വിവരം കണ്ടെത്താൻ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"പ്രൊഫൈൽ, ഉപകരണ ഉടമകളെ നിയന്ത്രിക്കുക"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"പ്രൊഫൈൽ ഉടമകളെയും ഉപകരണ ഉടമയെയും സജ്ജമാക്കാൻ അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"പ്രവർത്തിക്കുന്ന അപ്ലിക്കേഷനുകൾ പുനഃക്രമീകരിക്കുക"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ടാസ്‌ക്കുകളെ മുന്നിലേക്കോ പശ്ചാത്തലത്തിലേക്കോ നീക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് അപ്ലിക്കേഷൻ നിങ്ങളുടെ ഇടപെടലില്ലാതെ ചെയ്യാനിടയുണ്ട്."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"കാർ മോഡ് പ്രവർത്തനക്ഷമമാക്കുക"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 63499e5..45576c1 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Апп нь WAP мессежийг хүлээн авах болон биелүүлэх боломжтой. Энэ зөвшөөрөл нь танд илгээсэн мессежийг танд харуулалгүйгээр хянах эсвэл устгах боломжийг агуулна."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ажиллаж байгаа апп-г дуудах"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Апп нь одоо ажиллаж байгаа болон сүүлд ажилласан даалгаврын талаарх мэдээллийг авах боломжтой. Ингэснээр апп нь төхөөмж дээрх ямар аппликешнүүд ашиглагдсан талаарх мэдээлийг олох боломжтой."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Профайл болон төхөөрөмжийн эзэмшигчийг удирдах"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Аппликейшнд профайл болон төхөөрөмж эзэмшигчийг сонгохыг зөвшөөрөх"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"ажиллаж байгаа апп-уудыг дахин эрэмбэлэх"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Апп нь даалгавруудыг нүүрлүү болон арлуу зөөх боломжтой. Апп нь энийг таны оролцоогүйгээр хийж болзошгүй"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"машины горимыг идэвхжүүлэх"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 9887f98..e52fe37 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP संदेश प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यासाठी अॅप ला अनुमती देते. ही परवानगी आपल्याला पाठविलेले संदेश आपल्याला न दर्शविता त्यांचे परीक्षण करण्याची आणि ते हटविण्याची क्षमता समाविष्ट करते."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"चालणारे अॅप्स पुनर्प्राप्त करा"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"सध्या आणि अलीकडे चालणार्‍या कार्यांविषयी माहिती पुनर्प्राप्त करण्यासाठी अॅप ला अनुमती देते. हे डिव्हाइसवर कोणते अनुप्रयोग वापरले जात आहेत त्याविषयी माहिती शोधण्यासाठी अॅप ला अनुमती देऊ शकतात."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"प्रोफाईल आणि डिव्हाइस मालक व्यवस्थापित करा"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"प्रोफाईल मालक आणि डिव्हाइस मालक सेट करण्याची अॅप्सना अनुमती द्या."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"चालणारे अॅप्स पुनर्क्रमित करा"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"समोर आणि पार्श्वभूमीवर कार्ये हलविण्यासाठी अॅप ला अनुमती देते. अॅप हे आपल्या इनपुटशिवाय करू शकतो."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सक्षम करा"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 93534fb..7d3a314 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Membenarkan apl menerima dan memproses mesej WAP. Kebenaran ini termasuk keupayaan untuk memantau atau memadam mesej yang dihantar kepada anda tanpa menunjukkannya kepada anda."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"dapatkan semula apl yang sedang dijalankan"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Membenarkan apl mengambil maklumat tentang tugasan yang sedang dan baru berjalan. Ini boleh membenarkan apl untuk menemui maklumat tentang apl mana yang digunakan pada peranti."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Urus profil dan pemilik peranti"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Membenarkan apl menetapkan profil pemilik dan pemilik peranti."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"susun semula tertib apl yang dijalankan"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Membenarkan apl memindahkan tugasan ke latar depan dan latar belakang. Apl boleh melakukan ini tanpa input anda."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"dayakan mod kereta"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 1bd372a..ffcf6b8 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"အပလီကေးရှင်းအား WAP စာများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"အလုပ်လုပ်နေကြသည့် appများကို ရယူခြင်း"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"အပလီကေးရှင်းအား လက်ရှိနဲ့ လတ်တလော လုပ်ဆောင်ခဲ့သော သတင်းအချက်အလက် အသေးစိတ်အား ထုတ်ယူခွင့်ပြုရန်။ အပလီကေးရှင်းမှ သင် ဘယ် အပလီကေးရှင်းများသုံးရှိကြောင့် တွေ့ရှိနိုင်ပါသည်"</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"ကိုယ်ရေးအချက်အလက်နှင့် စက်ပစ္စည်းပိုင်ရှင်များကို စီမံပါ"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ကိုယ်ရေးအချက်လက်ပိုင်ရှင်များနှင့်စက်ပစ္စည်းပိုင်ရှင်အား သတ်မှတ်ရန် App အားခွင့်ပြုပါ။"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"အလုပ်လုပ်နေကြသည့် appများကို ပြန်လည်စီစဉ်ခြင်း"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"အပလီကေးရှင်းအား နောက်ကွယ် နှင့် ရှေ့မှောက်တွင် လက်ရှိ လုပ်ဆောင်နေမှုများအား ဖယ်ခွင့် ပြုပါ။ သင့် ခွင့်ပြုချက်မပါပဲ လုပ်ဆောင်နိုင်ပါလိမ့်မည်"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ကားမောင်းနေစဥ်စနစ်အား ရရှိစေခြင်း"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c36fe11..47ff2a0 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Lar appen motta og behandle WAP-meldinger. Dette betyr at appen kan overvåke eller slette meldinger som er sendt til deg uten at du har sett dem."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"hente apper som kjører"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Lar appen hente informasjon om oppgaver som kjører og som nylig har kjørt. Dette kan tillate appen å oppdage informasjon om hvilke apper som brukes på enheten."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Administrer profiler og enhetseiere"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Lar apper angi profileierne og enhetseieren."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Endre rekkefølge på apper som kjører"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Lar appen flytte oppgaver til forgrunnen eller bakgrunnen. Appen kan gjøre dette uten instruksjoner fra deg."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivere bilmodus"</string>
diff --git a/core/res/res/values-night/themes_material_daynight.xml b/core/res/res/values-night/themes_material_daynight.xml
index da870b7..b344582 100644
--- a/core/res/res/values-night/themes_material_daynight.xml
+++ b/core/res/res/values-night/themes_material_daynight.xml
@@ -93,6 +93,11 @@
          (large, xlarge). -->
     <style name="Theme.Material.DayNight.DialogWhenLarge" parent="Theme.Material.DialogWhenLarge" />
 
+    <!-- Theme for a window with a dark action bar that will be displayed
+         either full-screen on smaller screens (small, normal) or as a dialog
+         on larger screens (large, xlarge). -->
+    <style name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" parent="Theme.Material.DialogWhenLarge" />
+
     <!-- Theme for a window without an action bar that will be displayed either full-screen
          on smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 2062233..f5d5e8e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Hiermee kan de app WAP-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"actieve apps ophalen"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Hiermee kan de app informatie ophalen over actieve en recent uitgevoerde taken. Zo kan de app informatie vinden over welke apps op het apparaat worden gebruikt."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profiel- en apparaateigenaren beheren"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Apps toestaan de profieleigenaren en apparaateigenaar in te stellen."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"actieve apps opnieuw rangschikken"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Hiermee kan de app taken naar de voor- en achtergrond verplaatsen. De app kan dit doen zonder om uw bevestiging te vragen."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"automodus inschakelen"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index bf34de2..e4aca19 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -276,10 +276,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Pozwala aplikacji na odbieranie i przetwarzanie wiadomości WAP. To oznacza, że aplikacja będzie mogła bez Twojej wiedzy monitorować i usuwać wiadomości wysyłane do Twojego urządzenia."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"pobieranie uruchomionych aplikacji"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Pozwala aplikacji na pobieranie informacji o aktualnie i niedawno działających zadaniach. Dzięki temu aplikacja może uzyskać informacje o tym, które aplikacje są używane na urządzeniu."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Zarządzanie właścicielami profilu i urządzenia"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Zezwala aplikacjom na ustawianie właścicieli profilu i urządzenia."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"zmienianie kolejności uruchomionych aplikacji"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Pozwala aplikacji na przenoszenie zadań między tłem a pierwszym planem. Aplikacja może to robić bez Twojego udziału."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"włączanie trybu samochodowego"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3dc8eda..e75620b 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite que a aplicação receba e processe mensagens WAP. Esta autorização inclui a capacidade de monitorizar ou eliminar mensagens enviadas para si sem as apresentar."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"obter aplicações em execução"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite que a aplicação recupere informações acerca de tarefas executadas atual e recentemente. Isto pode permitir que a aplicação descubra informações acerca de quais as aplicações utilizadas no dispositivo."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gerir proprietários de perfis e do dispositivo"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permite que as aplicações definam proprietários de perfis e o proprietário do dispositivo."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar as aplicações em execução"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que a aplicação mova tarefas para primeiro e segundo plano. A aplicação poderá fazê-lo sem qualquer entrada do utilizador."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar modo de carro"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 7eec3ab..f2c8527 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite que o app receba e processe mensagens WAP. Esta permissão inclui a capacidade de monitorar ou excluir mensagens enviadas para você sem mostrá-las para você."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"recuperar apps em execução"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite que o app obtenha informações sobre tarefas em execução atuais e recentes. Pode permitir que o app descubra informações sobre os apps usados ​​no dispositivo."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gerenciar proprietários de perfis e de dispositivos"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permitir que os apps definam os proprietários de perfis e de dispositivos."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar os apps em execução"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que o app mova tarefas para o primeiro plano e o plano de fundo, sem sua intervenção."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar o modo carro"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 0ca77cf..df7e778 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -275,10 +275,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite aplicației să primească și să proceseze mesaje WAP. Această permisiune include capacitatea de a monitoriza sau şterge mesajele care v-au fost trimise fără a vi le arăta."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"preluare aplicații care rulează"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite aplicației să preia informaţiile despre activităţile care rulează în prezent și care au rulat recent. În acest fel, aplicația poate descoperi informaţii despre aplicațiile care sunt utilizate pe dispozitiv."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gestionează proprietarii de profiluri și proprietarul dispozitivului"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permite aplicațiilor să seteze proprietarii de profiluri și proprietarul dispozitivului."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordonare aplicații care rulează"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite aplicației să mute activităţile în prim-plan și în fundal. Aplicaţia poate face acest lucru fără aportul dvs."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"activare mod Maşină"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 9b8f564..8b6d913 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -276,10 +276,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Приложение сможет получать и обрабатывать WAP-сообщения. Это значит, что оно сможет отслеживать и удалять отправленные на ваше устройство сообщения, не показывая их."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"Получение данных о запущенных приложениях"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Приложение сможет получать информацию о недавно запущенных и выполняемых задачах, а следовательно, и о приложениях, используемых на устройстве."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Управление профилями и владельцами"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Приложения смогут определять владельцев профилей и владельца устройства."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Упорядочивание запущенных приложений"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Приложение сможет переключать активный и фоновый режимы выполнения задач без вашего ведома."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"Включение режима громкой связи"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 23a9023..498dcde 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -276,10 +276,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Umožňuje aplikácii prijímať a spracovávať správy WAP. Toto povolenie zahŕňa možnosť sledovať vaše správy alebo ich odstrániť bez toho, aby sa vám zobrazili."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"načítať spustené aplikácie"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Umožňuje aplikácii načítať informácie o aktuálne či nedávno spustených úlohách. Toto povolenie môže aplikácii umožniť objaviť informácie o tom, ktoré aplikácie sa na zariadení používajú."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Správa vlastníkov profilov a zariadenia"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Povolí aplikáciám nastaviť vlastníkov profilov a vlastníka zariadenia."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"zmeniť poradie spustených aplikácií"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Umožňuje aplikácii presunúť úlohy do popredia alebo do pozadia. Aplikácia tak môže urobiť bez vášho zásahu."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivovať režim V aute"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 99ab0bd..77f9a1f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -276,10 +276,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Aplikaciji omogoča prejemanje in obdelavo sporočil WAP. S tem lahko aplikacija nadzoruje ali izbriše sporočila, poslana v napravo, ne da bi vam jih pokazala."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"dobivanje aplikacij, ki se izvajajo"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Aplikaciji omogoča prejemanje podatkov o trenutnih in nedavno izvajajočih se opravilih. S tem lahko aplikacija odkrije podatke o aplikacijah, ki se uporabljajo v napravi."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Upravljanje lastnikov profilov in lastnika naprave."</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Dovolite aplikacijam, da nastavijo lastnike profilov in lastnika naprave."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"preurejanje aplikacij, ki se izvajajo"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Aplikaciji omogoča premikanje opravil v ospredje in ozadje. Aplikacija lahko to naredi brez vašega nadzora."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"omogočanje načina delovanja v avtomobilu"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 76e5215..e3e6f1d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -275,10 +275,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Дозвољава апликацији да прима и обрађује WAP поруке. Ова дозвола укључује могућност праћења или брисања порука које вам се шаљу, а које вам се не приказују."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"преузимање покренутих апликација"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Дозвољава апликацији да преузима информације о актуелним и недавно покренутим задацима. Ово може да омогући апликацији да открије информације о томе које се апликације користе на уређају."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Управљај власницима профила и уређаја"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Дозвољава апликацији да подеси власнике профила и власника уређаја."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"промена редоследа покренутих апликација"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Дозвољава апликацији да премешта задатке у први план и у позадину. Апликација може да ради ово без вашег уноса."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"омогућавање режима рада у аутомобилу"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 257f7c3..b78e632 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Tillåter att appen tar emot och hanterar WAP-meddelanden. Med den här behörigheten kan appen övervaka eller ta bort meddelanden som skickats till dig utan att visa dem för dig."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"hämta appar som körs"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Tillåter att appen hämtar information om nyligen körda och pågående aktiviteter. Detta kan innebära att appen tillåts ta reda på vilka appar som används på enheten."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Hantera profil- och enhetsägare"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Tillåter att appar anger profilägare och enhetsägare."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"byt ordning på appar som körs"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Tillåter att appen flyttar aktiviteter till förgrunden eller bakgrunden. Appen kan göra detta utan åtgärd från dig."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivera trafikläge"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index dcdef95..8c58d5b 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Inaruhusu programu kupokea na kuchakata ujumbe wa WAP. Idhini hii inajumuisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwako bila ya kukuonyesha."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"rudisha programu zinazoendeshwa"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Inaruhusu programu kurudisha taarifa kuhusu kazi zinazoendeshwa sasa na hivi karibuni. Hii inaweza kuruhusu programu kugundua taarifa kuhusu ni programu zipi zinazotumika kwenye kifaa."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Simamia wamiliki wa wasifu na kifaa"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Huruhusu programu kuweka wamiliki wa wasifu na mmiliki wa kifaa."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Agiza tena programu za kuendeshwa"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Inaruhusu programu kusongesha kazi hadi kwenye mandhari-mbele na mandari nyuma. Programu inaweza kufanya haya bila ya maingizo yako."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"Wezesha mtindo wa gari"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 6040ccb..a33af51 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP செய்திகளைப் பெற, செயற்படுத்தப் பயன்பாட்டை அனுமதிக்கிறது. உங்களுக்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்க அல்லது நீக்குவதற்கான திறன் இந்த அனுமதியில் உள்ளடங்கும்."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"இயங்கும் பயன்பாடுகளை மீட்டெடுத்தல்"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"நடப்பில் மற்றும் சமீபத்தில் இயங்கும் காரியங்களின் தகவலைப் பெற பயன்பாட்டை அனுமதிக்கிறது. சாதனத்தில் எந்தப் பயன்பாடுகள் பயன்படுத்தப்படுகின்றன என்பது குறித்த தகவலைக் கண்டறிய பயன்பாட்டை இது அனுமதிக்கலாம்."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"சுயவிவரத்தையும் சாதன உரிமையாளர்களையும் நிர்வகிக்கவும்"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"சுயவிவர உரிமையாளர்களையும் சாதன உரிமையாளரையும் அமைக்க, பயன்பாடுகளை அனுமதிக்கிறது."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"இயங்கும் பயன்பாடுகளை மறுவரிசைப்படுத்தல்"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"பின்புலத்திலும், முன்புலத்திலும் காரியங்களை நகர்த்த பயன்பாட்டை அனுமதிக்கிறது. உங்கள் உள்ளீடு இல்லாமலே பயன்பாடு இதைச் செய்யலாம்."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"கார் பயன்முறையை இயக்குதல்"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 272e7e2..6bd4007 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీకు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగల లేదా తొలగించగల సామర్థ్యాన్ని కలిగి ఉంటుంది."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"అమలవుతున్న అనువర్తనాలను పునరుద్ధరించడం"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"ప్రస్తుతం మరియు ఇటీవల అమలవుతున్న విధుల గురించి వివరణాత్మక సమాచారాన్ని తిరిగి పొందడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది పరికరంలో ఉపయోగించబడిన అనువర్తనాల గురించి సమాచారాన్ని కనుగొనడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"ప్రొఫైల్ మరియు పరికరం యజమానులను నిర్వహించడానికి అనుమతి"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"ప్రొఫైల్ యజమానులను మరియు పరికరం యజమానిని సెట్ చేయడానికి అనువర్తనాలను అనుమతిస్తుంది."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"అమలవుతున్న అనువర్తనాలను మళ్లీ క్రమం చేయడం"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"విధులను ముందుకు మరియు నేపథ్యానికి తరలించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మీ ప్రమేయం లేకుండానే దీన్ని చేయవచ్చు."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"కారు మోడ్‌ను ప్రారంభించడం"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 45a2d7a..501ce0a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความ WAP การอนุญาตนี้รวมถึงความสามารถในการตรวจสอบหรือลบข้อความที่ส่งมาให้คุณโดยไม่ต้องแสดงให้คุณเห็น"</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"เรียกแอปพลิเคชันที่ทำงานอยู่"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"อนุญาตให้แอปพลิเคชันเรียกดูข้อมูลเกี่ยวกับงานที่ดำเนินการอยู่ในขณะนี้และเมื่อเร็วๆ นี้ ซึ่งอาจทำให้แอปพลิเคชันสามารถค้นข้อมูลได้ว่าอุปกรณ์นี้ใช้แอปพลิเคชันใดบ้าง"</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"จัดการเจ้าของโปรไฟล์และอุปกรณ์"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"อนุญาตให้แอปตั้งค่าเจ้าของโปรไฟล์และเจ้าของอุปกรณ์"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"จัดลำดับแอปพลิเคชันที่ทำงานอยู่ใหม่"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"อนุญาตให้แอปพลิเคชันย้ายงานไปยังส่วนหน้าและพื้นหลัง แอปพลิเคชันอาจดำเนินการโดยไม่รอคำสั่งจากคุณ"</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"เปิดใช้งานโหมดใช้ในรถยนต์"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 6d6c48b..545bcd5 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Pinapayagan ang app na tumanggap at magproseso ng mga mensaheng WAP. Kabilang sa pahintulot na ito ang kakayahang sumubaybay o magtanggal ang app ng mga mensaheng ipinapadala sa iyo nang hindi ipinapakita ang mga ito sa iyo."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"bawiin ang tumatakbong apps"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Pinapayagan ang app na kumuha ng impormasyon tungkol sa mga kasalukuyan at kamakailang gumaganang gawain. Maaari nitong payagan ang app na tumuklas ng impormasyon tungkol sa kung aling mga application ang ginagamit sa device."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Pamahalaan ang mga may-ari ng profile at device"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Nagbibigay-daan sa mga app na itakda ang mga may-ari ng profile at ang may-ari ng device."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"muling isaayos ang tumatakbong apps"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Pinapayagan ang app na maglipat ng mga gawain sa foreground at background. Maaari itong gawin ng app nang wala ng iyong input."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"paganahin ang car mode"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 54528a4..527f09a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -276,10 +276,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Дозволяє програмі отримувати й обробляти WAP-повідомлення. Це означає, що програма може відстежувати чи видаляти повідомлення, надіслані на ваш пристрій, навіть не показуючи їх вам."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"отримувати запущені програми"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Дозволяє програмі отримувати інформацію про поточні й останні запущені завдання. Це може дозволити програмі виявляти інформацію про програми, які використовуються на пристрої."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Керування власниками профілю та пристрою"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Додатки можуть вибирати власника профілю та пристрою."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"змінювати порядок запущених програм"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Дозволяє програмі переміщувати завдання в активні чи фонові вікна. Програма може робити це без вашого відома."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"увімк. режим авто"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 1ecb9bb..ec1a840 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -274,10 +274,8 @@
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Ilovaga WAP xabarlarni qabul qilish va ularni qayta ishlash uchun ruxsat beradi. Ushbu huquq sizga ko‘rsatmasdan sizga yuborilgan xabarlarni kuzatish yoki o‘chirish xususiyatiga ham ega."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"ishlab turgan ilovalar to‘g‘risida ma’lumot olish"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Ilovaga hozirda va so‘nggi ishga tushirilgan vazifalar haqida to‘liq ma’lumot olishiga ruxsat beradi. Bu ilovaga qurilmadagi ishlatilayotgan ilovalar haqidagi ma’lumotlarga ega bo‘lishiga ruxsat berishi mumkin."</string>
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (5979288447973722097) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Profil va qurilma egalarini boshqarish"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Ilovaga profil va qurilma egalarini sozlash uchun ruxsat beradi"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"ishlab turgan ilovalarni qayta tartiblash"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ilovalarga vazifalarni old va orqa fonga o‘tkazish uchun ruxsat beradi. Ilova buni sizning yordamingizsiz bajarishi mumkin."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"mashina usulini yoqish"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 887b0a5..a95cc79 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1971,7 +1971,7 @@
              {@link android.R.attr#windowTranslucentStatus}.
              Corresponds to setting {@link android.view.View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR} on
              the decor view. -->
-        <attr name="windowHasLightStatusBar" format="boolean" />
+        <attr name="windowLightStatusBar" format="boolean" />
     </declare-styleable>
 
     <!-- The set of attributes that describe a AlertDialog's theme. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0c685e0..4631427 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1044,7 +1044,8 @@
 
          <p>NOTE: The value of {@link android.R.attr#screenOrientation} will be ignored for
          resizeable activities as the system doesn't support fixed orientation on a resizeable
-         activity. -->
+         activity.
+         @hide -->
     <attr name="resizeableActivity" format="boolean" />
 
     <!-- This value indicates how tasks rooted at this activity will behave in lockTask mode.
@@ -1796,6 +1797,7 @@
         <attr name="autoRemoveFromRecents" />
         <attr name="relinquishTaskIdentity" />
         <attr name="resumeWhilePausing" />
+        <!-- @hide -->
         <attr name="resizeableActivity" />
         <attr name="lockTaskMode" />
         <attr name="showForAllUsers" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 07f8c60..56eab2c 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2126,4 +2126,7 @@
 
     <!-- Keyguard component -->
     <string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
+
+    <!-- This config is used to force VoiceInteractionService to start on certain low ram devices. -->
+    <bool name="config_forceEnableVoiceInteractionService">false</bool>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 875659d..dd4c134 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2610,10 +2610,9 @@
 
   <public type="attr" name="trackTint" />
   <public type="attr" name="trackTintMode" />
-  <public type="attr" name="resizeableActivity" />
   <public type="attr" name="start" />
   <public type="attr" name="end" />
-  <public type="attr" name="windowHasLightStatusBar" />
+  <public type="attr" name="windowLightStatusBar" />
   <public type="attr" name="numbersInnerTextColor" />
   <public type="attr" name="iconTint" />
   <public type="attr" name="iconTintMode" />
@@ -2643,6 +2642,8 @@
   <public type="style" name="ThemeOverlay.Material.Dialog" />
   <public type="style" name="TextAppearance.Material.Widget.Button.Inverse" />
   <public type="style" name="ThemeOverlay.Material.Dialog.Alert" />
+  <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
+  <public type="style" name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" />
 
   <public type="id" name="pasteAsPlainText" />
   <public type="id" name="undo" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 51c2062..3146f41 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3012,6 +3012,26 @@
     <!-- Notification action to browse external media [CHAR LIMIT=20] -->
     <string name="ext_media_browse_action">Explore</string>
 
+    <!-- Notification title when external media is missing [CHAR LIMIT=30] -->
+    <string name="ext_media_missing_title"><xliff:g id="name" example="SD card">%s</xliff:g> missing</string>
+    <!-- Notification body when external media is missing [CHAR LIMIT=30] -->
+    <string name="ext_media_missing_message">Reinsert this device</string>
+
+    <!-- Notification title when moving an application to external storage [CHAR LIMIT=30] -->
+    <string name="ext_media_move_specific_title">Moving <xliff:g id="name" example="Calculator">%s</xliff:g></string>
+    <!-- Notification title when moving data to external storage [CHAR LIMIT=32] -->
+    <string name="ext_media_move_title">Moving data</string>
+
+    <!-- Notification title when moving data to external storage [CHAR LIMIT=32] -->
+    <string name="ext_media_move_success_title">Move complete</string>
+    <!-- Notification title when moving data to external storage [CHAR LIMIT=64] -->
+    <string name="ext_media_move_success_message">Data moved to <xliff:g id="name" example="SD card">%s</xliff:g></string>
+
+    <!-- Notification title when moving data to external storage failed [CHAR LIMIT=32] -->
+    <string name="ext_media_move_failure_title">Couldn\'t move data</string>
+    <!-- Notification title when moving data to external storage failed [CHAR LIMIT=64] -->
+    <string name="ext_media_move_failure_message">Data left at original location</string>
+
     <!-- Shown in LauncherActivity when the requested target Intent didn't return any matching Activities, leaving the list empty. -->
     <string name="activity_list_empty">No matching activities found.</string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5b13325..90437b9 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -280,6 +280,7 @@
   <java-symbol type="bool" name="config_enableScreenshotChord" />
   <java-symbol type="bool" name="config_bluetooth_default_profiles" />
   <java-symbol type="bool" name="config_enableWifiDisplay" />
+  <java-symbol type="bool" name="config_forceEnableVoiceInteractionService" />
   <java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
   <java-symbol type="bool" name="config_safe_media_volume_enabled" />
   <java-symbol type="bool" name="config_camera_sound_forced" />
@@ -1898,6 +1899,14 @@
   <java-symbol type="string" name="ext_media_init_action" />
   <java-symbol type="string" name="ext_media_unmount_action" />
   <java-symbol type="string" name="ext_media_browse_action" />
+  <java-symbol type="string" name="ext_media_missing_title" />
+  <java-symbol type="string" name="ext_media_missing_message" />
+  <java-symbol type="string" name="ext_media_move_specific_title" />
+  <java-symbol type="string" name="ext_media_move_title" />
+  <java-symbol type="string" name="ext_media_move_success_title" />
+  <java-symbol type="string" name="ext_media_move_success_message" />
+  <java-symbol type="string" name="ext_media_move_failure_title" />
+  <java-symbol type="string" name="ext_media_move_failure_message" />
   <java-symbol type="string" name="usb_storage_error_message" />
   <java-symbol type="string" name="usb_storage_message" />
   <java-symbol type="string" name="usb_storage_notification_message" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index e8aab07..e679e0a 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -56,11 +56,11 @@
 
         <item name="textColorPrimary">@color/primary_text_material_dark</item>
         <item name="textColorPrimaryInverse">@color/primary_text_material_light</item>
-        <item name="textColorPrimaryActivated">@color/primary_text_activated_material_dark</item>
+        <item name="textColorPrimaryActivated">@color/primary_text_inverse_when_activated_material</item>
         <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_dark</item>
         <item name="textColorSecondary">@color/secondary_text_material_dark</item>
         <item name="textColorSecondaryInverse">@color/secondary_text_material_light</item>
-        <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_dark</item>
+        <item name="textColorSecondaryActivated">@color/secondary_text_inverse_when_activated_material</item>
         <item name="textColorTertiary">@color/secondary_text_material_dark</item>
         <item name="textColorTertiaryInverse">@color/secondary_text_material_light</item>
         <item name="textColorHint">@color/hint_foreground_material_dark</item>
@@ -410,10 +410,10 @@
 
         <item name="textColorPrimary">@color/primary_text_material_light</item>
         <item name="textColorPrimaryInverse">@color/primary_text_material_dark</item>
-        <item name="textColorPrimaryActivated">@color/primary_text_activated_material_light</item>
+        <item name="textColorPrimaryActivated">@color/primary_text_inverse_when_activated_material</item>
         <item name="textColorSecondary">@color/secondary_text_material_light</item>
         <item name="textColorSecondaryInverse">@color/secondary_text_material_dark</item>
-        <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_light</item>
+        <item name="textColorSecondaryActivated">@color/secondary_text_inverse_when_activated_material</item>
         <item name="textColorTertiary">@color/secondary_text_material_light</item>
         <item name="textColorTertiaryInverse">@color/secondary_text_material_dark</item>
         <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_light</item>
@@ -760,7 +760,7 @@
          status bar contents. -->
     <style name="Theme.Material.Light.LightStatusBar">
         <item name="colorPrimaryDark">@color/primary_dark_material_light_light_status_bar</item>
-        <item name="windowHasLightStatusBar">true</item>
+        <item name="windowLightStatusBar">true</item>
     </style>
 
     <style name="ThemeOverlay" />
@@ -777,10 +777,8 @@
 
         <item name="textColorPrimary">@color/primary_text_material_light</item>
         <item name="textColorPrimaryInverse">@color/primary_text_material_dark</item>
-        <item name="textColorPrimaryActivated">@color/primary_text_activated_material_light</item>
         <item name="textColorSecondary">@color/secondary_text_material_light</item>
         <item name="textColorSecondaryInverse">@color/secondary_text_material_dark</item>
-        <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_light</item>
         <item name="textColorTertiary">@color/secondary_text_material_light</item>
         <item name="textColorTertiaryInverse">@color/secondary_text_material_dark</item>
         <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_light</item>
@@ -814,11 +812,9 @@
 
         <item name="textColorPrimary">@color/primary_text_material_dark</item>
         <item name="textColorPrimaryInverse">@color/primary_text_material_light</item>
-        <item name="textColorPrimaryActivated">@color/primary_text_activated_material_dark</item>
         <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_dark</item>
         <item name="textColorSecondary">@color/secondary_text_material_dark</item>
         <item name="textColorSecondaryInverse">@color/secondary_text_material_light</item>
-        <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_dark</item>
         <item name="textColorTertiary">@color/secondary_text_material_dark</item>
         <item name="textColorTertiaryInverse">@color/secondary_text_material_light</item>
         <item name="textColorHint">@color/hint_foreground_material_dark</item>
@@ -1239,6 +1235,11 @@
          (large, xlarge). -->
     <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light" />
 
+    <!-- Theme for a window with a dark title bar that will be displayed either
+         full-screen on smaller screens (small, normal) or as a dialog on larger screens
+         (large, xlarge). -->
+    <style name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" parent="@style/Theme.Material.Light.DarkActionBar" />
+
     <!-- Theme for a window without an action bar that will be displayed either full-screen
          on smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
@@ -1283,6 +1284,16 @@
         <item name="panelMenuListTheme">@style/Theme.Material.Settings.CompactMenu</item>
     </style>
 
+    <!-- Default theme for Settings and activities launched from Settings. -->
+    <style name="Theme.Material.Settings.NoActionBar" parent="Theme.Material.DayNight.NoActionBar">
+        <item name="colorPrimary">@color/material_blue_grey_900</item>
+        <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
+
+        <item name="presentationTheme">@style/Theme.Material.Settings.Dialog.Presentation</item>
+        <item name="searchDialogTheme">@style/Theme.Material.Settings.SearchBar</item>
+        <item name="panelMenuListTheme">@style/Theme.Material.Settings.CompactMenu</item>
+    </style>
+
     <style name="Theme.Material.Settings.BaseDialog" parent="Theme.Material.DayNight.BaseDialog">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
@@ -1297,6 +1308,16 @@
 
     <style name="Theme.Material.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.BaseAlert" />
 
+    <style name="Theme.Material.Settings.DialogWhenLarge" parent="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar">
+        <item name="colorPrimary">@color/material_blue_grey_900</item>
+        <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
+    </style>
+
+    <style name="Theme.Material.Settings.DialogWhenLarge.NoActionBar" parent="Theme.Material.DayNight.DialogWhenLarge.NoActionBar">
+        <item name="colorPrimary">@color/material_blue_grey_900</item>
+        <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
+    </style>
+
     <style name="Theme.Material.Settings.Dialog.Presentation" parent="Theme.Material.DayNight.Dialog.Presentation">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
@@ -1305,7 +1326,6 @@
     <style name="Theme.Material.Settings.SearchBar" parent="Theme.Material.DayNight.SearchBar">
         <item name="colorPrimary">@color/material_blue_grey_900</item>
         <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
-        <item name="colorAccent">@color/material_deep_teal_500</item>
     </style>
 
     <style name="Theme.Material.Settings.CompactMenu" parent="Theme.Material.DayNight.CompactMenu">
diff --git a/core/res/res/values/themes_material_daynight.xml b/core/res/res/values/themes_material_daynight.xml
index 5d9b860..4ecca6b 100644
--- a/core/res/res/values/themes_material_daynight.xml
+++ b/core/res/res/values/themes_material_daynight.xml
@@ -93,6 +93,11 @@
          (large, xlarge). -->
     <style name="Theme.Material.DayNight.DialogWhenLarge" parent="Theme.Material.Light.DialogWhenLarge" />
 
+    <!-- Theme for a window with a dark action bar that will be displayed
+         either full-screen on smaller screens (small, normal) or as a dialog
+         on larger screens (large, xlarge). -->
+    <style name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" parent="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
+
     <!-- Theme for a window without an action bar that will be displayed either full-screen
          on smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index e04c214..4b82c3d 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -184,10 +184,10 @@
         result.putInt("ap-discovered", ssidAppearInScanResultsCount);
         getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
         if (i == mScanIterations + 1) {
-            writeOutput(String.format("iteration %d out of %d", i, mScanIterations));
+            writeOutput(String.format("iteration %d out of %d", i - 1, mScanIterations));
             writeOutput(String.format("average scanning time is %d", scanTimeSum / (i - 1)));
             writeOutput(String.format("ssid appear %d out of %d scan iterations",
-                    ssidAppearInScanResultsCount, i));
+                    ssidAppearInScanResultsCount, i - 1));
         }
     }
 
@@ -289,7 +289,7 @@
         getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
         if (i == mReconnectIterations + 1) {
             writeOutput(String.format("iteration %d out of %d",
-                    i, mReconnectIterations));
+                    i - 1, mReconnectIterations));
         }
     }
 }
diff --git a/docs/html-intl/intl/es/index.jd b/docs/html-intl/intl/es/index.jd
new file mode 100644
index 0000000..3c63b11
--- /dev/null
+++ b/docs/html-intl/intl/es/index.jd
@@ -0,0 +1,93 @@
+fullpage=true
+page.viewport_width=970
+excludeFromSuggestions=true
+page.metaDescription=El sitio oficial para los desarrolladores de Android. Proporciona el SDK de Android y la documentación para los diseñadores y desarrolladores de aplicaciones.
+page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
+
+@jd:body
+
+<div class="home-new-carousel-1">
+  <div class="fullscreen-carousel-content">
+    <div class="vcenter">
+      <div class="wrap clearfix">
+
+        <div class="static resource-flow-layout wrap col-16">
+          <div class="resource resource-card resource-card-18x6">
+
+      <div class="landing-section-header">
+            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="510" style="margin:20px 30px 0 30px"></div>
+            <div class="col-5" style=" margin-top:70px ">
+            <h3 stye="font-weight:300;">Android 5.0 Lollipop</h3>
+            <p>La actualización 5.0 de Android agrega una variedad de nuevas características para sus aplicaciones, como notificaciones en la pantalla de bloqueo, una nueva API de cámara, OpenGL ES 3.1, una nueva interfaz llamada "Material design", y mucho más.</p>
+            <a href="{@docRoot}about/versions/lollipop.html" class="landing-button landing-primary">Más información</a>
+            </div>
+          </div>
+          </div>
+        </div>
+       <h2>&nbsp;</h2>
+        <div style="margin-top:20px;height:115px" class="resource-widget resource-flow-layout wrap col-16
+        no-section" data-query="collection:index/primary" data-resourcestyle="card"
+        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> <!-- end .resource-widget -->
+      </div> <!-- end .wrap -->
+    </div> <!-- end .vcenter -->
+  </div> <!-- end .fullscreen-carousel-content -->
+</div> <!-- end .fullscreen-carousel -->
+
+<div class="actions-bar" style="margin-top:20px">
+  <div class="wrap">
+    <div class="actions">
+      <div><a href="{@docRoot}sdk/index.html">Obtener el SDK</a></div>
+      <div><a href="{@docRoot}samples/index.html">Examinar muestras</a></div>
+      <div><a href="//www.youtube.com/user/androiddevelopers">Mirar videos</a></div>
+      <div><a href="{@docRoot}distribute/googleplay/developer-console.html">Administrar tus aplicaciones</a></div>
+    </div><!-- end .actions -->
+  </div><!-- end .wrap -->
+</div><!-- end .actions-bar -->
+
+
+
+<div class="landing-rest-of-page">
+  <div class="landing-section">
+    <div class="wrap">
+      <div class="landing-section-header">
+
+            <div class="landing-h1" style="margin-top:0px">Creado para un mundo de múltiples pantallas</div>
+        <div class="landing-subhead" style="margin-top: 20px;">
+          Android se ejecuta en cientos de millones de dispositivos de todo el mundo, <br>
+          y ahora es compatible con estos innovadores factores de forma.
+        </div>
+      </div>
+      <div class="landing-body" style="margin-top: 50px;">
+        <div class="landing-breakout cols">
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/wear-wordmark.png"> <img src="{@docRoot}images/home/wear.png">
+              <p class="landing-small">
+                Proporciona información dinámica para tus usuarios, cuando la necesiten.
+            </p>
+            <p class="landing-small">
+              <a href="{@docRoot}wear/index.html">Obtener información sobre Android Wear</a>
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/tv-wordmark.png"> <img src="{@docRoot}images/home/tv.png">
+              <p class="landing-small">
+                Crea aplicaciones para televisores y dale vida a tus contenidos.
+              </p>
+            <p class="landing-small">
+              <a href="{@docRoot}tv/index.html">Obtener información sobre Android TV</a>
+
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/auto-wordmark.png"> <img src="{@docRoot}images/home/auto.png">
+              <p class="landing-small">
+                Extiende tus aplicaciones de música para los sistemas de entretenimiento para automóviles.
+             </p>
+            <p class="landing-small">
+              <a href="{@docRoot}auto/index.html">Más información sobre Android Auto</a>
+            </p>
+          </div>
+        </div>
+      </div>
+    </div>  <!-- end .wrap -->
+  </div> <!-- end .landing-section -->
\ No newline at end of file
diff --git a/docs/html-intl/intl/ja/index.jd b/docs/html-intl/intl/ja/index.jd
new file mode 100644
index 0000000..e0153fa
--- /dev/null
+++ b/docs/html-intl/intl/ja/index.jd
@@ -0,0 +1,93 @@
+fullpage=true
+page.viewport_width=970
+excludeFromSuggestions=true
+page.metaDescription=Android デベロッパー向け公式サイトアプリのデベロッパーおよびデザイナー向け Android SDK とドキュメンテーションを提供します。
+page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
+
+@jd:body
+
+<div class="home-new-carousel-1">
+  <div class="fullscreen-carousel-content">
+    <div class="vcenter">
+      <div class="wrap clearfix">
+
+        <div class="static resource-flow-layout wrap col-16">
+          <div class="resource resource-card resource-card-18x6">
+
+      <div class="landing-section-header">
+            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="510" style="margin:20px 30px 0 30px"></div>
+            <div class="col-5" style=" margin-top:70px ">
+            <h3 stye="font-weight:300;">Android 5.0 Lollipop</h3>
+            <p>Android 5.0 アップデートでは、ロック画面での通知、新しいカメラ API、OpenGL ES 3.1、新たなマテリアル デザイン インターフェースなど、ご使用のアプリにさまざまな新しい機能を提供します。</p>
+            <a href="{@docRoot}about/versions/lollipop.html" class="landing-button landing-primary">詳細を見る</a>
+            </div>
+          </div>
+          </div>
+        </div>
+       <h2>&nbsp;</h2>
+        <div style="margin-top:20px;height:115px" class="resource-widget resource-flow-layout wrap col-16
+        no-section" data-query="collection:index/primary" data-resourcestyle="card"
+        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> <!-- end .resource-widget -->
+      </div> <!-- end .wrap -->
+    </div> <!-- end .vcenter -->
+  </div> <!-- end .fullscreen-carousel-content -->
+</div> <!-- end .fullscreen-carousel -->
+
+<div class="actions-bar" style="margin-top:20px">
+  <div class="wrap">
+    <div class="actions">
+      <div><a href="{@docRoot}sdk/index.html">SDK を入手する</a></div>
+      <div><a href="{@docRoot}samples/index.html">サンプルを見る</a></div>
+      <div><a href="//www.youtube.com/user/androiddevelopers">ビデオを見る</a></div>
+      <div><a href="{@docRoot}distribute/googleplay/developer-console.html">アプリを管理する</a></div>
+    </div><!-- end .actions -->
+  </div><!-- end .wrap -->
+</div><!-- end .actions-bar -->
+
+
+
+<div class="landing-rest-of-page">
+  <div class="landing-section">
+    <div class="wrap">
+      <div class="landing-section-header">
+
+            <div class="landing-h1" style="margin-top:0px">マルチ スクリーンの世界を<br>構築しましょう</div>
+        <div class="landing-subhead" style="margin-top: 20px;">
+          Android は世界中の数多くの携帯型デバイスで使われています。 <br>
+          そして今回、これらの新しいフォーム ファクタをサポートします。
+        </div>
+      </div>
+      <div class="landing-body" style="margin-top: 50px;">
+        <div class="landing-breakout cols">
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/wear-wordmark.png"> <img src="{@docRoot}images/home/wear.png">
+              <p class="landing-small">
+                いつでもどこでも、アプリのユーザーに必要な情報を提供します。
+            </p>
+            <p class="landing-small">
+              <a href="{@docRoot}wear/index.html">Android Wear の詳細を見る</a>
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/tv-wordmark.png"> <img src="{@docRoot}images/home/tv.png">
+              <p class="landing-small">
+                大画面向けアプリを作成して、コンテンツを生き生きと表現します。
+              </p>
+            <p class="landing-small">
+              <a href="{@docRoot}tv/index.html">Android TV の詳細を見る</a>
+
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/auto-wordmark.png"> <img src="{@docRoot}images/home/auto.png">
+              <p class="landing-small">
+                音楽アプリを車載エンターテイメント システムに対応させます。
+             </p>
+            <p class="landing-small">
+              <a href="{@docRoot}auto/index.html">Android Auto の詳細を見る</a>
+            </p>
+          </div>
+        </div>
+      </div>
+    </div>  <!-- end .wrap -->
+  </div> <!-- end .landing-section -->
\ No newline at end of file
diff --git a/docs/html-intl/intl/ko/index.jd b/docs/html-intl/intl/ko/index.jd
new file mode 100644
index 0000000..59b9321
--- /dev/null
+++ b/docs/html-intl/intl/ko/index.jd
@@ -0,0 +1,93 @@
+fullpage=true
+page.viewport_width=970
+excludeFromSuggestions=true
+page.metaDescription=Android 개발자 공식 사이트 앱 개발자 및 디자이너에게 Android SDK 및 문서를 제공합니다.
+page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
+
+@jd:body
+
+<div class="home-new-carousel-1">
+  <div class="fullscreen-carousel-content">
+    <div class="vcenter">
+      <div class="wrap clearfix">
+
+        <div class="static resource-flow-layout wrap col-16">
+          <div class="resource resource-card resource-card-18x6">
+
+      <div class="landing-section-header">
+            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="510" style="margin:20px 30px 0 30px"></div>
+            <div class="col-5" style=" margin-top:70px ">
+            <h3 stye="font-weight:300;">Android 5.0 Lollipop</h3>
+            <p>Android 5.0 업데이트는 사용자 앱에 잠금화면상의 알림, 완전히 새로운 카메라 API, OpenGL ES 3.1, 신규 머티리얼 디자인(Material Design) 인터페이스 등 다양하고 새로운 기능을 추가합니다.</p>
+            <a href="{@docRoot}about/versions/lollipop.html" class="landing-button landing-primary">자세히 알아보기</a>
+            </div>
+          </div>
+          </div>
+        </div>
+       <h2>&nbsp;</h2>
+        <div style="margin-top:20px;height:115px" class="resource-widget resource-flow-layout wrap col-16
+        no-section" data-query="collection:index/primary" data-resourcestyle="card"
+        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> <!-- end .resource-widget -->
+      </div> <!-- end .wrap -->
+    </div> <!-- end .vcenter -->
+  </div> <!-- end .fullscreen-carousel-content -->
+</div> <!-- end .fullscreen-carousel -->
+
+<div class="actions-bar" style="margin-top:20px">
+  <div class="wrap">
+    <div class="actions">
+      <div><a href="{@docRoot}sdk/index.html">SDK 받기</a></div>
+      <div><a href="{@docRoot}samples/index.html">샘플 둘러보기</a></div>
+      <div><a href="//www.youtube.com/user/androiddevelopers">비디오 시청</a></div>
+      <div><a href="{@docRoot}distribute/googleplay/developer-console.html">앱 관리</a></div>
+    </div><!-- end .actions -->
+  </div><!-- end .wrap -->
+</div><!-- end .actions-bar -->
+
+
+
+<div class="landing-rest-of-page">
+  <div class="landing-section">
+    <div class="wrap">
+      <div class="landing-section-header">
+
+            <div class="landing-h1" style="margin-top:0px">멀티스크린 월드에 맞게 만들기</div>
+        <div class="landing-subhead" style="margin-top: 20px;">
+          Android는 전 세계 수억 개의 휴대 기기에서 구동되고 있으며, <br>
+          이제 이 흥미진진하고 새로운 폼팩터를 지원합니다.
+        </div>
+      </div>
+      <div class="landing-body" style="margin-top: 50px;">
+        <div class="landing-breakout cols">
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/wear-wordmark.png"> <img src="{@docRoot}images/home/wear.png">
+              <p class="landing-small">
+                사용자가 필요로 할 때 언제든지 실시간으로 정보를 제공합니다.
+            </p>
+            <p class="landing-small">
+              <a href="{@docRoot}wear/index.html">Android Wear에 대해 알아보세요</a>
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/tv-wordmark.png"> <img src="{@docRoot}images/home/tv.png">
+              <p class="landing-small">
+                대형 스크린에 적합한 앱과 컨텐츠를 구성하세요.
+              </p>
+            <p class="landing-small">
+              <a href="{@docRoot}tv/index.html">Android TV에 대해 알아보세요</a>
+
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/auto-wordmark.png"> <img src="{@docRoot}images/home/auto.png">
+              <p class="landing-small">
+                음악 앱을 자동차 엔터테인먼트 시스템에 적용해보세요.
+             </p>
+            <p class="landing-small">
+              <a href="{@docRoot}auto/index.html">Android Auto에 대해 알아보세요</a>
+            </p>
+          </div>
+        </div>
+      </div>
+    </div>  <!-- end .wrap -->
+  </div> <!-- end .landing-section -->
\ No newline at end of file
diff --git a/docs/html-intl/intl/pt-br/index.jd b/docs/html-intl/intl/pt-br/index.jd
new file mode 100644
index 0000000..bf6c57d
--- /dev/null
+++ b/docs/html-intl/intl/pt-br/index.jd
@@ -0,0 +1,93 @@
+fullpage=true
+page.viewport_width=970
+excludeFromSuggestions=true
+page.metaDescription=O site oficial dos desenvolvedores Android. Fornece o Android SDK e a documentação para desenvolvedores e projetistas de aplicativos.
+page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" /> 
+
+@jd:body
+
+<div class="home-new-carousel-1">
+  <div class="fullscreen-carousel-content">
+    <div class="vcenter">
+      <div class="wrap clearfix">
+
+        <div class="static resource-flow-layout wrap col-16">
+          <div class="resource resource-card resource-card-18x6">
+
+      <div class="landing-section-header">
+            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="510" style="margin:20px 30px 0 30px"></div>
+            <div class="col-5" style=" margin-top:70px ">
+            <h3 stye="font-weight:300;">Android 5.0 Lollipop</h3>
+            <p>A atualização do Android 5.0 adiciona diversos novos recursos aos aplicativos, como notificações na tela de bloqueio, uma API de câmera totalmente nova, OpenGL ES 3.1, a nova interface do Material Design e muito mais.</p>
+            <a href="{@docRoot}about/versions/lollipop.html" class="landing-button landing-primary">Saiba mais</a>
+            </div>
+          </div>
+          </div>
+        </div>
+       <h2>&nbsp;</h2>
+        <div style="margin-top:20px;height:115px" class="resource-widget resource-flow-layout wrap col-16
+        no-section" data-query="collection:index/primary" data-resourcestyle="card"
+        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> <!-- end .resource-widget -->
+      </div> <!-- end .wrap -->
+    </div> <!-- end .vcenter -->
+  </div> <!-- end .fullscreen-carousel-content -->
+</div> <!-- end .fullscreen-carousel -->
+
+<div class="actions-bar" style="margin-top:20px">
+  <div class="wrap">
+    <div class="actions">
+      <div><a href="{@docRoot}sdk/index.html">Obtenha o SDK</a></div>
+      <div><a href="{@docRoot}samples/index.html">Procure amostras</a></div>
+      <div><a href="//www.youtube.com/user/androiddevelopers">Assista a vídeos</a></div>
+      <div><a href="{@docRoot}distribute/googleplay/developer-console.html">Gerencie seus aplicativos</a></div>
+    </div><!-- end .actions -->
+  </div><!-- end .wrap -->
+</div><!-- end .actions-bar -->
+
+
+
+<div class="landing-rest-of-page">
+  <div class="landing-section">
+    <div class="wrap">
+      <div class="landing-section-header">
+
+            <div class="landing-h1" style="margin-top:0px">Crie para um mundo multitela</div>
+        <div class="landing-subhead" style="margin-top: 20px;">
+          O Android funciona em milhões de dispositivos portáteis em todo o mundo <br>
+          e agora é compatível com esses novos e empolgantes recursos.
+        </div>
+      </div>
+      <div class="landing-body" style="margin-top: 50px;">
+        <div class="landing-breakout cols">
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/wear-wordmark.png"><img src="{@docRoot}images/home/wear.png">
+              <p class="landing-small">
+                Forneça informações constantemente aos usuários, sempre que precisarem.
+            </p>
+            <p class="landing-small">
+              <a href="{@docRoot}wear/index.html">Conheça o Android Wear</a>
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/tv-wordmark.png"> <img src="{@docRoot}images/home/tv.png">
+              <p class="landing-small">
+                Crie aplicativos para a telona e dê vida ao conteúdo.
+              </p>
+            <p class="landing-small">
+              <a href="{@docRoot}tv/index.html">Conheça o Android TV</a>
+
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/auto-wordmark.png"> <img src="{@docRoot}images/home/auto.png">
+              <p class="landing-small">
+                Estenda seus aplicativos de música a sistema de entretenimento de automóveis.
+             </p>
+            <p class="landing-small">
+              <a href="{@docRoot}auto/index.html">Conheça o Android Auto</a>
+            </p>
+          </div>
+        </div>
+      </div>
+    </div>  <!-- end .wrap -->
+  </div> <!-- end .landing-section -->
\ No newline at end of file
diff --git a/docs/html-intl/intl/ru/index.jd b/docs/html-intl/intl/ru/index.jd
new file mode 100644
index 0000000..eb7ffe4
--- /dev/null
+++ b/docs/html-intl/intl/ru/index.jd
@@ -0,0 +1,93 @@
+fullpage=true
+page.viewport_width=970
+excludeFromSuggestions=true
+page.metaDescription=Официальный сайт для разработчиков Android. На этом сайте вы найдете пакеты Android SDK и документацию для дизайнеров и разработчиков приложений.
+page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
+
+@jd:body
+
+<div class="home-new-carousel-1">
+  <div class="fullscreen-carousel-content">
+    <div class="vcenter">
+      <div class="wrap clearfix">
+
+        <div class="static resource-flow-layout wrap col-16">
+          <div class="resource resource-card resource-card-18x6">
+
+      <div class="landing-section-header">
+            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="510" style="margin:20px 30px 0 30px"></div>
+            <div class="col-5" style=" margin-top:70px ">
+            <h3 stye="font-weight:300;">Android 5.0 Lollipop</h3>
+            <p>Обновление Android 5.0 содержит различные новые возможности для приложений: уведомления на заблокированном экране, совершено новый API камеры, OpenGL ES 3.1, новый интерфейс Material Design и множество других функций.</p>
+            <a href="{@docRoot}about/versions/lollipop.html" class="landing-button landing-primary">Подробнее</a>
+            </div>
+          </div>
+          </div>
+        </div>
+       <h2>&nbsp;</h2>
+        <div style="margin-top:20px;height:115px" class="resource-widget resource-flow-layout wrap col-16
+        no-section" data-query="collection:index/primary" data-resourcestyle="card"
+        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> <!-- end .resource-widget -->
+      </div> <!-- end .wrap -->
+    </div> <!-- end .vcenter -->
+  </div> <!-- end .fullscreen-carousel-content -->
+</div> <!-- end .fullscreen-carousel -->
+
+<div class="actions-bar" style="margin-top:20px">
+  <div class="wrap">
+    <div class="actions">
+      <div><a href="{@docRoot}sdk/index.html">Пакет SDK</a></div>
+      <div><a href="{@docRoot}samples/index.html">Примеры</a></div>
+      <div><a href="//www.youtube.com/user/androiddevelopers">Видеоролики</a></div>
+      <div><a href="{@docRoot}distribute/googleplay/developer-console.html">Управление приложениями</a></div>
+    </div><!-- end .actions -->
+  </div><!-- end .wrap -->
+</div><!-- end .actions-bar -->
+
+
+
+<div class="landing-rest-of-page">
+  <div class="landing-section">
+    <div class="wrap">
+      <div class="landing-section-header">
+
+            <div class="landing-h1" style="margin-top:0px">ОС для многоэкранных устройств</div>
+        <div class="landing-subhead" style="margin-top: 20px;">
+          Сотни миллионов мобильных устройств по всему миру работают под управлением операционной системы Android. <br>
+          А теперь эта система радует и обладателей устройств других форм-факторов.
+        </div>
+      </div>
+      <div class="landing-body" style="margin-top: 50px;">
+        <div class="landing-breakout cols">
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/wear-wordmark.png"> <img src="{@docRoot}images/home/wear.png">
+              <p class="landing-small">
+                Предоставляйте пользователям информацию прямо на ходу, когда бы им это ни потребовалось.
+            </p>
+            <p class="landing-small">
+              <a href="{@docRoot}wear/index.html">Подробнее об Android Wear</a>
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/tv-wordmark.png"> <img src="{@docRoot}images/home/tv.png">
+              <p class="landing-small">
+                Создавайте приложения для использования на большом экране телевизора и разрабатывайте динамичный контент.
+              </p>
+            <p class="landing-small">
+              <a href="{@docRoot}tv/index.html">Подробнее об Android TV</a>
+
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/auto-wordmark.png"> <img src="{@docRoot}images/home/auto.png">
+              <p class="landing-small">
+                Автомобильные мультимедийные системы — прекрасная возможность расширить список поддерживаемых устройств для музыкальных приложений.
+             </p>
+            <p class="landing-small">
+              <a href="{@docRoot}auto/index.html">Подробнее об Android Auto</a>
+            </p>
+          </div>
+        </div>
+      </div>
+    </div>  <!-- end .wrap -->
+  </div> <!-- end .landing-section -->
\ No newline at end of file
diff --git a/docs/html-intl/intl/zh-cn/index.jd b/docs/html-intl/intl/zh-cn/index.jd
index 590332f..1c2fb99 100644
--- a/docs/html-intl/intl/zh-cn/index.jd
+++ b/docs/html-intl/intl/zh-cn/index.jd
@@ -1,15 +1,11 @@
 fullpage=true
 page.viewport_width=970
 excludeFromSuggestions=true
-page.metaDescription=The official site for Android developers. Provides the Android SDK and documentation for app developers and designers.
+page.metaDescription=Android 开发人员的官方网站。为应用开发人员以及设计师提供 Android SDK 和文档。
 page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
 
 @jd:body
 
-
-
-
-
 <div class="home-new-carousel-1">
   <div class="fullscreen-carousel-content">
     <div class="vcenter">
@@ -19,38 +15,31 @@
           <div class="resource resource-card resource-card-18x6">
 
       <div class="landing-section-header">
-            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png"
-                 srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x"
-                 width="510" style="margin:20px 30px 0 30px"></div>
+            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="510" style="margin:20px 30px 0 30px"></div>
             <div class="col-5" style=" margin-top:70px ">
             <h3 stye="font-weight:300;">Android 5.0 Lollipop</h3>
-            <p>在 Android 5.0 的版本更新中,我们添加了多种可用于你的应用程序的新功能,比如锁屏通知,一个全新的相机API,OpenGL ES 3.1,以及新的 Material Design 界面等等。</p>
+            <p>Android 5.0 更新将为您的应用增添各种新功能,例如锁定屏幕通知、全新的相机 API、OpenGL ES 3.1、全新的 Material Design 界面等等。</p>
             <a href="{@docRoot}about/versions/lollipop.html" class="landing-button landing-primary">了解详情</a>
             </div>
           </div>
           </div>
         </div>
        <h2>&nbsp;</h2>
-        
-        <div style="margin-top:20px" class="resource-widget resource-flow-layout wrap col-16
-        no-section" data-query="collection:index/primary/zhcn" data-resourcestyle="card"
-        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> 
-
+        <div style="margin-top:20px;height:115px" class="resource-widget resource-flow-layout wrap col-16
+        no-section" data-query="collection:index/primary" data-resourcestyle="card"
+        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> <!-- end .resource-widget -->
       </div> <!-- end .wrap -->
     </div> <!-- end .vcenter -->
   </div> <!-- end .fullscreen-carousel-content -->
 </div> <!-- end .fullscreen-carousel -->
 
-
-
-
 <div class="actions-bar" style="margin-top:20px">
   <div class="wrap">
     <div class="actions">
-      <div><a href="/sdk/index.html">下载 SDK</a></div>
-      <div><a href="/samples/index.html">浏览示例</a></div>
+      <div><a href="{@docRoot}sdk/index.html">获得 SDK</a></div>
+      <div><a href="{@docRoot}samples/index.html">浏览示例</a></div>
       <div><a href="//www.youtube.com/user/androiddevelopers">观看视频</a></div>
-      <div><a href="/distribute/googleplay/developer-console.html">管理应用</a></div>
+      <div><a href="{@docRoot}distribute/googleplay/developer-console.html">管理您的应用</a></div>
     </div><!-- end .actions -->
   </div><!-- end .wrap -->
 </div><!-- end .actions-bar -->
@@ -61,44 +50,41 @@
   <div class="landing-section">
     <div class="wrap">
       <div class="landing-section-header">
-        
-            <div class="landing-h1" style="margin-top:0px">专为跨屏世界打造</div>
-        <div class="landing-subhead" style="margin-top:20px">
-          全球数亿手持设备安装的都是 Android 系统。<br />
-          现在 Android 系统还支持以下这些备受期待的新设备。
+
+            <div class="landing-h1" style="margin-top:0px">专为多屏幕时代而设</div>
+        <div class="landing-subhead" style="margin-top: 20px;">
+          Android 在全球各地的数亿台手持设备上运行, <br>
+          如今更支持下列激动人心的新设备和配置。
         </div>
       </div>
-      <div class="landing-body" style="margin-top:50px">
+      <div class="landing-body" style="margin-top: 50px;">
         <div class="landing-breakout cols">
           <div class="col-3-wide">
-              <img src="{@docRoot}images/home/wear-wordmark.png" />
-              <img src="{@docRoot}images/home/wear.png" />
+              <img src="{@docRoot}images/home/wear-wordmark.png"> <img src="{@docRoot}images/home/wear.png">
               <p class="landing-small">
-                让用户随时随地获得需要的信息。
+                让您的用户即便在途中亦能随时随地获得所需的信息。
             </p>
             <p class="landing-small">
-              <a href="/wear/index.html">了解 Android Wear</a>
+              <a href="{@docRoot}wear/index.html">了解关于 Android Wear 的信息</a>
             </p>
           </div>
           <div class="col-3-wide">
-              <img src="{@docRoot}images/home/tv-wordmark.png" />
-             <img src="{@docRoot}images/home/tv.png" />
+              <img src="{@docRoot}images/home/tv-wordmark.png"> <img src="{@docRoot}images/home/tv.png">
               <p class="landing-small">
-                针对大屏幕打造应用,使你的内容引人入胜。
+                将您的应用搬上大屏幕,使您的内容栩栩如生。
               </p>
             <p class="landing-small">
-              <a href="/tv/index.html">了解 Android TV</a>
+              <a href="{@docRoot}tv/index.html">了解关于 Android TV 的信息</a>
 
             </p>
           </div>
           <div class="col-3-wide">
-              <img src="{@docRoot}images/home/auto-wordmark.png" />
-              <img src="{@docRoot}images/home/auto.png" />
+              <img src="{@docRoot}images/home/auto-wordmark.png"> <img src="{@docRoot}images/home/auto.png">
               <p class="landing-small">
-                将你的音乐应用扩展到车载娱乐系统。
+                将您的音乐应用扩展至车载娱乐系统。
              </p>
             <p class="landing-small">
-              <a href="/auto/index.html">了解 Android Auto</a>
+              <a href="{@docRoot}auto/index.html">了解关于 Android Auto 的信息</a>
             </p>
           </div>
         </div>
diff --git a/docs/html-intl/intl/zh-tw/index.jd b/docs/html-intl/intl/zh-tw/index.jd
new file mode 100644
index 0000000..56ae4cf
--- /dev/null
+++ b/docs/html-intl/intl/zh-tw/index.jd
@@ -0,0 +1,92 @@
+fullpage=true
+page.viewport_width=970excludeFromSuggestions=true
+page.metaDescription=適用於 Android 開發人員的官方網站。提供適用於應用程式開發人員與設計師的 Android SDK 與文件。
+page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" /> 
+
+@jd:body
+
+<div class="home-new-carousel-1">
+  <div class="fullscreen-carousel-content">
+    <div class="vcenter">
+      <div class="wrap clearfix">
+
+        <div class="static resource-flow-layout wrap col-16">
+          <div class="resource resource-card resource-card-18x6">
+
+      <div class="landing-section-header">
+            <div class="col-10"><img src="{@docRoot}images/home/l-hero_2x.png" srcset="{@docRoot}images/home/l-hero.png 1x, {@docRoot}images/home/l-hero_2x.png 2x" width="510" style="margin:20px 30px 0 30px"></div>
+            <div class="col-5" style=" margin-top:70px ">
+            <h3 stye="font-weight:300;">Android 5.0 棒棒糖</h3>
+            <p>Android 5.0 更新新增了許多新功能到您的應用程式,例如鎖定螢幕上的通知、全新的相機 API、OpenGL ES 3.1、新的材料設計介面,還有更多其他功能。</p>
+            <a href="{@docRoot}about/versions/lollipop.html" class="landing-button landing-primary">深入了解</a>
+            </div>
+          </div>
+          </div>
+        </div>
+       <h2>&nbsp;</h2>
+        <div style="margin-top:20px;height:115px" class="resource-widget resource-flow-layout wrap col-16
+        no-section" data-query="collection:index/primary" data-resourcestyle="card"
+        data-sortorder="-timestamp" data-maxresults="3" data-cardsizes="6x2,6x2,6x2"></div> <!-- end .resource-widget -->
+      </div> <!-- end .wrap -->
+    </div> <!-- end .vcenter -->
+  </div> <!-- end .fullscreen-carousel-content -->
+</div> <!-- end .fullscreen-carousel -->
+
+<div class="actions-bar" style="margin-top:20px">
+  <div class="wrap">
+    <div class="actions">
+      <div><a href="{@docRoot}sdk/index.html">取得 SDK</a></div>
+      <div><a href="{@docRoot}samples/index.html">瀏覽範例</a></div>
+      <div><a href="//www.youtube.com/user/androiddevelopers">觀賞影片</a></div>
+      <div><a href="{@docRoot}distribute/googleplay/developer-console.html">管理您的應用程式</a></div>
+    </div><!-- end .actions -->
+  </div><!-- end .wrap -->
+</div><!-- end .actions-bar -->
+
+
+
+<div class="landing-rest-of-page">
+  <div class="landing-section">
+    <div class="wrap">
+      <div class="landing-section-header">
+
+            <div class="landing-h1" style="margin-top:0px">針對多螢幕世界建置</div>
+        <div class="landing-subhead" style="margin-top: 20px;">
+          Android 在全球數百萬部手持式裝置上執行, <br>
+          而且它現在支援這些令人興奮、各種尺寸的裝置。
+        </div>
+      </div>
+      <div class="landing-body" style="margin-top: 50px;">
+        <div class="landing-breakout cols">
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/wear-wordmark.png"> <img src="{@docRoot}images/home/wear.png">
+              <p class="landing-small">
+                為您的使用者提供可隨時隨地存取的資訊。
+            </p>
+            <p class="landing-small">
+              <a href="{@docRoot}wear/index.html">了解 Android Wear</a>
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/tv-wordmark.png"> <img src="{@docRoot}images/home/tv.png">
+              <p class="landing-small">
+                為大螢幕建置您的應用程式,並將您的內容帶到生活中。
+              </p>
+            <p class="landing-small">
+              <a href="{@docRoot}tv/index.html">了解 Android TV</a>
+
+            </p>
+          </div>
+          <div class="col-3-wide">
+              <img src="{@docRoot}images/home/auto-wordmark.png"> <img src="{@docRoot}images/home/auto.png">
+              <p class="landing-small">
+                將您的音樂應用程式延伸到車用娛樂系統。
+             </p>
+            <p class="landing-small">
+              <a href="{@docRoot}auto/index.html">了解 Android Auto</a>
+            </p>
+          </div>
+        </div>
+      </div>
+    </div>  <!-- end .wrap -->
+  </div> <!-- end .landing-section -->
\ No newline at end of file
diff --git a/docs/html/distribute/tools/promote/brand.jd b/docs/html/distribute/tools/promote/brand.jd
index a12e753..cf83a5e 100644
--- a/docs/html/distribute/tools/promote/brand.jd
+++ b/docs/html/distribute/tools/promote/brand.jd
@@ -37,6 +37,18 @@
       <p>If used with your logo, "for Android" should be no larger than 90% of your logo’s size.
       First instance of this use should be followed by a TM symbol, "for Android&trade;".</p>
     </li>
+    <li>"Android TV", "Android Wear" and "Android Auto" may only be used to identify or market
+      products or services with prior approval.  Use "for Android" or "with Android" for all
+      other Android-based products
+      <ul>
+        <li><span style="color:red">Incorrect</span>: "Android TV Streaming Stick",
+          "Streaming Stick with Android TV"</li>
+        <li><span style="color:green">Correct</span>: "Streaming Stick with Android"</li>
+      </ul>
+      <p>If used with your logo, "for Android" or "with Android" should be no larger than 90% of
+        your logo’s size. First instance of this use should be followed by a TM symbol,
+        "for Android&trade;".</p>
+    </li>
     <li>Android may be used as a descriptor, as long as it is followed by a
         proper generic term. (Think of "Android" as a term used in place of
         "the Android platform.")
diff --git a/docs/html/google/auth/api-client.jd b/docs/html/google/auth/api-client.jd
index e33721d..8f926f5 100644
--- a/docs/html/google/auth/api-client.jd
+++ b/docs/html/google/auth/api-client.jd
@@ -99,20 +99,23 @@
 href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code
 GoogleApiClient}</a> by appending
 additional calls to
-<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#addApi(com.google.android.gms.common.api.Api)"
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#addApi(com.google.android.gms.common.api.Api<? extends com.google.android.gms.common.api.Api.ApiOptions.NotRequiredOptions>)"
 >{@code addApi()}</a> and
 <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#addScope(com.google.android.gms.common.api.Scope)"
 >{@code addScope()}</a>.</p>
 
 <p class="caution">
-<strong>Important:</strong> To avoid client connection errors on devices that do not have the
+<strong>Important:</strong> If you are adding multiple APIs to a
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code>GoogleApiClient</code></a>,
+you may run into client connection errors on devices that do not have the
 <a href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
-Wear app</a> installed, use a separate <a
-href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code
-GoogleApiClient}</a> instance to access only the <a
+Wear app</a> installed. To avoid connection errors, call the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#addApiIfAvailable(com.google.android.gms.common.api.Api<? extends com.google.android.gms.common.api.Api.ApiOptions.NotRequiredOptions>, com.google.android.gms.common.api.Scope...)">{@code addApiIfAvailable()}</a>
+method and pass in the <a
 href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code
-Wearable}</a> API. For more information, see <a href="#WearableApi">Access the Wearable
-API</a>.</p>
+Wearable}</a> API to indicate that your client should gracefully handle the missing API.
+For more information, see <a
+href="{@docRoot}google/auth/api-client.html#WearableApi">Access the Wearable API</a>.</p>
 
 <p>Before you can begin a connection by calling <a
 href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html#connect()"
@@ -421,27 +424,52 @@
 
 <h3 id="WearableApi">Access the Wearable API</h3>
 
-<p>On devices that do not have the <a
-href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
-Wear app</a> installed, connection requests that include the <a
+<p>The Wearable API provides a communication channel for your handheld and wearable apps. The API
+consists of a set of data objects that the system can send and synchronize over the wire and
+listeners that notify your apps of important events with the data layer. The
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API is available on devices running Android 4.3 (API level 18) or higher when a wearable device is
+connected. The API is not available under the following conditions:
+</p>
+
+<ul>
+<li>Devices running Android 4.2 (API level 17) or earlier.</li>
+<li><a href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
+Wear companion app</a> is not installed on the device.</li>
+<li>Android Wear device is not connected.</li>
+</ul>
+
+<h4 id="OnlyWearableApi">Using only the Wearable API</h4>
+
+<p>If your app uses the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API but not other Google APIs, you can add this API by calling the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#addApi(com.google.android.gms.common.api.Api<? extends com.google.android.gms.common.api.Api.ApiOptions.NotRequiredOptions>)"
+>{@code addApi()}</a> method. The following example shows how to add the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API to your <a
+href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code
+GoogleApiClient}</a> instance:</p>
+
+<pre>
+GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
+    .addApi(Wearable.API)
+    .build();
+</pre>
+
+<p>In situations where the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API is not available, connection requests that include the <a
 href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code
 Wearable}</a> API fail with the <a
 href="{@docRoot}reference/com/google/android/gms/common/ConnectionResult.html#API_UNAVAILABLE">
-<code>API_UNAVAILABLE</code></a> error code. If your app uses the <a
-href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code
-Wearable}</a> API in addition to other Google APIs, use a separate <a
-href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code
-GoogleApiClient}</a> instance to access the <a
-href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code
-Wearable}</a> API. This approach enables you to access other Google APIs on devices that are not
-paired with a wearable device.</p>
+<code>API_UNAVAILABLE</code></a> error code.</p>
 
-<p>When you use a separate <a
-href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code
-GoogleApiClient}</a> instance to access only the Wearable API, you can determine
-whether the <a
-href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
-Wear app</a> is installed on the device:</p>
+<p>
+The following example shows how to determine whether the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API is available:
+</p>
 
 <pre>
 // Connection failed listener method for a client that only
@@ -449,15 +477,55 @@
 &#64;Override
 public void onConnectionFailed(ConnectionResult result) {
     if (result.getErrorCode() == ConnectionResult.API_UNAVAILABLE) {
-        // The Android Wear app is not installed
+        // The Wearable API is unavailable
     }
     ...
 }
 </pre>
 
 
+<h4 id="WearableApiWithOthers">Using the Wearable API with other APIs</h4>
 
+<p>
+If your app uses the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API in addition to other Google APIs, call the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#addApiIfAvailable(com.google.android.gms.common.api.Api<? extends com.google.android.gms.common.api.Api.ApiOptions.NotRequiredOptions>, com.google.android.gms.common.api.Scope...)">addApiIfAvailable()</a>
+method and pass in the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API to indicate that your client should gracefully handle the missing API.</p>
 
+<p>The following example shows how to access the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API along with the
+<a href="{@docRoot}reference/com/google/android/gms/drive/DriveApi.html">{@code Drive}</a>
+API:</p>
+
+<pre>
+// Create a GoogleApiClient instance
+mGoogleApiClient = new GoogleApiClient.Builder(this)
+        .addApi(Drive.API)
+        .addApiIfAvailable(Wearable.API)
+        .addScope(Drive.SCOPE_FILE)
+        .addConnectionCallbacks(this)
+        .addOnConnectionFailedListener(this)
+        .build();
+</pre>
+
+<p>In the example above, the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>
+can successfully connect with the Google Drive service without connecting to the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API if it is unavailable. After you connect your
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>
+instance, ensure that the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code Wearable}</a>
+API is available before making the API calls:
+</p>
+
+<pre>
+mGoogleApiClient.hasConnectedApi(Wearable.API);
+</pre>
 
 
 <h2 id="Communicating">Communicate with Google Services</h2>
diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd
index a4fc2d2..217db81 100644
--- a/docs/html/training/articles/keystore.jd
+++ b/docs/html/training/articles/keystore.jd
@@ -29,7 +29,9 @@
 <p>The Android Keystore system lets you store cryptographic keys in a container
   to make it more difficult to extract from the device. Once keys are in the
   keystore, they can be used for cryptographic operations with the key material
-  remaining non-exportable.</p>
+  remaining non-exportable. Moreover, it offers facilities to restrict when and
+  how keys can be used, such as requiring user authentication for key use or
+  restricting encryption keys to be used only in certain block modes.</p>
 
 <p>The Keystore system is used by the {@link
   android.security.KeyChain} API as well as the Android
@@ -112,3 +114,27 @@
 <p>Similarly, verify data with the {@link java.security.Signature#verify(byte[])} method:</p>
 
 {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java verify}
+
+<h3 id="UserAuthentication">Requiring User Authentication For Key Use</h3>
+
+<p>When generating or importing a key into the {@code AndroidKeyStore} you can specify that the key
+can only be used if user has been authenticated. The user is authenticated using a subset of their
+secure lock screen credentials. This is a security measure which makes it possible to generate
+cryptographic assertions about the user having been authenticated.
+
+<p>When a key is configured to require user authentication, it is also configured to operate in one
+of the two modes:
+<ul>
+<li>User authentication is valid for a duration of time. All keys in this mode are authorized
+  for use as soon as the user unlocks the secure lock screen or confirms their secure lock screen
+  credentials using the {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence) KeyguardManager.createConfirmDeviceCredentialIntent}
+  flow. Each key specifies for how long the authorization remains valid for that key. Such keys
+  can only be generated or imported if the secure lock screen is enabled (see {@link android.app.KeyguardManager#isKeyguardSecure Keyguard.isKeyguardSecure}).
+  These keys become permanently invalidated once the secure lock screen is disabled or forcibly
+  reset (e.g. by a Device Admin).</li>
+<li>User authentication is required for every use of the key. In this mode, a specific operation
+  involving a specific key is authorized by the user. Currently, the only means of such
+  authorization is fingerprint authentication: {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, int) FingerprintManager.authenticate}.
+  Such keys can only be generated or imported if at least one fingerprint is enrolled (see {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}).
+  These keys become permanently invalidated once all fingerprints are unenrolled.</li>
+</ul>
diff --git a/docs/html/training/wearables/data-layer/accessing.jd b/docs/html/training/wearables/data-layer/accessing.jd
index 0c0a2d5..482b30c 100644
--- a/docs/html/training/wearables/data-layer/accessing.jd
+++ b/docs/html/training/wearables/data-layer/accessing.jd
@@ -61,13 +61,16 @@
 </pre>
 
 <p class="caution">
-<strong>Important:</strong> To avoid client connection errors on devices that do not have the
+<strong>Important:</strong> If you are adding multiple APIs to a
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code>GoogleApiClient</code></a>,
+you may run into client connection errors on devices that do not have the
 <a href="https://play.google.com/store/apps/details?id=com.google.android.wearable.app&hl=en">Android
-Wear app</a> installed, use a separate <a
-href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code
-GoogleApiClient}</a> instance to access only the <a
+Wear app</a> installed. To avoid connection errors, call the
+<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html#addApiIfAvailable(com.google.android.gms.common.api.Api<? extends com.google.android.gms.common.api.Api.ApiOptions.NotRequiredOptions>, com.google.android.gms.common.api.Scope...)">{@code addApiIfAvailable()}</a>
+method and pass in the <a
 href="{@docRoot}reference/com/google/android/gms/wearable/Wearable.html">{@code
-Wearable}</a> API. For more information, see <a
+Wearable}</a> API to indicate that your client should gracefully handle the missing API.
+For more information, see <a
 href="{@docRoot}google/auth/api-client.html#WearableApi">Access the Wearable API</a>.</p>
 
 <p>Before you use the data layer API, start a connection on your client by calling the
diff --git a/docs/html/training/wearables/data-layer/messages.jd b/docs/html/training/wearables/data-layer/messages.jd
index 0826e6b..ef9bfb1 100644
--- a/docs/html/training/wearables/data-layer/messages.jd
+++ b/docs/html/training/wearables/data-layer/messages.jd
@@ -10,6 +10,12 @@
   <li><a href="#SendMessage">Send a Message</a></li>
   <li><a href="#ReceiveMessage">Receive a Message</a></li>
 </ol>
+<h2>Try it out</h2>
+<ul>
+  <li>
+    <a href="https://github.com/googlesamples/android-FindMyPhone/" class="external-link">FindMyPhone</a>
+  </li>
+</ul>
 </div>
 </div>
 
@@ -28,7 +34,7 @@
 
 <p>Multiple wearable devices can be connected to a user’s handheld device. Each connected device in
 the network is considered a <em>node</em>. With multiple connected devices, you must consider which
-nodes receive the messages. For example, In a voice transcription app that receives voice data on
+nodes receive the messages. For example, in a voice transcription app that receives voice data on
 the wearable device, you should send the message to a node with the processing power and battery
 capacity to handle the request, such as a handheld device.</p>
 
@@ -138,6 +144,19 @@
 }
 </pre>
 
+<p class="note"><strong>Note:</strong>
+If you create a service that extends
+<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>
+to detect capability changes, you may want to override the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onConnectedNodes(java.util.List<com.google.android.gms.wearable.Node>)"><code>onConnectedNodes()</code></a>
+method to listen to finer-grained connectivity details, such as when a wearable device switches
+from Wi-Fi to a Bluetooth connection to the handset. For an example implementation, see the
+<code>DisconnectListenerService</code> class in the
+<a href="https://github.com/googlesamples/android-FindMyPhone/" class="external-link">FindMyPhone</a>
+sample. For more information on how to listen for important events, see
+<a href="{@docRoot}training/wearables/data-layer/events.html#Listen">Listen for Data Layer Events</a>.
+</p>
+
 <p>After detecting the capable nodes, determine where to send the message. You should pick a node
 that is in close proximity to your wearable device to
 minimize message routing through multiple nodes. A nearby node is defined as one that is directly
@@ -177,7 +196,15 @@
 
 <p>The following example shows how to send a message to the transcription-capable node from a
 wearable device. Verify that the node is available before you attempt to send the message. This call
-is synchronous and blocks processing until the message is received or until the request times out.
+is synchronous and blocks processing until the system queues the message for delivery.
+</p>
+
+<p class="note"><strong>Note:</strong> A successful result code does not guarantee delivery of the
+message. If your app requires data reliability, use
+<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
+objects or the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/ChannelApi.html"><code>ChannelApi</code></a>
+class to send data between devices.
 </p>
 
 <pre>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 2acb8ba..9fe8e0c 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -81,17 +81,9 @@
      */
     protected int mScreenDensity = Bitmap.DENSITY_NONE;
 
-    /**
-     * Flag for drawTextRun indicating left-to-right run direction.
-     * @hide
-     */
-    public static final int DIRECTION_LTR = 0;
-
-    /**
-     * Flag for drawTextRun indicating right-to-left run direction.
-     * @hide
-     */
-    public static final int DIRECTION_RTL = 1;
+    // Used by native code
+    @SuppressWarnings("UnusedDeclaration")
+    private int mSurfaceFormat;
 
     // Maximum bitmap size as defined in Skia's native code
     // (see SkCanvas.cpp, SkDraw.cpp)
@@ -1724,10 +1716,15 @@
     }
 
     /**
-     * Render a run of all LTR or all RTL text, with shaping. This does not run
-     * bidi on the provided text, but renders it as a uniform right-to-left or
-     * left-to-right run, as indicated by dir. Alignment of the text is as
-     * determined by the Paint's TextAlign value.
+     * Draw a run of text, all in a single direction, with optional context for complex text
+     * shaping.
+     *
+     * <p>See {@link #drawTextRun(CharSequence, int, int, int, int, float, float, boolean, Paint)}
+     * for more details. This method uses a character array rather than CharSequence to
+     * represent the string. Also, to be consistent with the pattern established in
+     * {@link #drawText}, in this method {@code count} and {@code contextCount} are used rather
+     * than offsets of the end position; {@code count = end - start, contextCount = contextEnd -
+     * contextStart}.
      *
      * @param text the text to render
      * @param index the start of the text to render
@@ -1735,13 +1732,12 @@
      * @param contextIndex the start of the context for shaping.  Must be
      *         no greater than index.
      * @param contextCount the number of characters in the context for shaping.
-     *         ContexIndex + contextCount must be no less than index
+     *         contexIndex + contextCount must be no less than index
      *         + count.
      * @param x the x position at which to draw the text
      * @param y the y position at which to draw the text
      * @param isRtl whether the run is in RTL direction
      * @param paint the paint
-     * @hide
      */
     public void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
             int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) {
@@ -1761,21 +1757,39 @@
     }
 
     /**
-     * Render a run of all LTR or all RTL text, with shaping. This does not run
-     * bidi on the provided text, but renders it as a uniform right-to-left or
-     * left-to-right run, as indicated by dir. Alignment of the text is as
-     * determined by the Paint's TextAlign value.
+     * Draw a run of text, all in a single direction, with optional context for complex text
+     * shaping.
+     *
+     * <p>The run of text includes the characters from {@code start} to {@code end} in the text. In
+     * addition, the range {@code contextStart} to {@code contextEnd} is used as context for the
+     * purpose of complex text shaping, such as Arabic text potentially shaped differently based on
+     * the text next to it.
+     *
+     * <p>All text outside the range {@code contextStart..contextEnd} is ignored. The text between
+     * {@code start} and {@code end} will be laid out and drawn.
+     *
+     * <p>The direction of the run is explicitly specified by {@code isRtl}. Thus, this method is
+     * suitable only for runs of a single direction. Alignment of the text is as determined by the
+     * Paint's TextAlign value. Further, {@code 0 <= contextStart <= start <= end <= contextEnd
+     * <= text.length} must hold on entry.
+     *
+     * <p>Also see {@link android.graphics.Paint#getRunAdvance} for a corresponding method to
+     * measure the text; the advance width of the text drawn matches the value obtained from that
+     * method.
      *
      * @param text the text to render
      * @param start the start of the text to render. Data before this position
      *            can be used for shaping context.
      * @param end the end of the text to render. Data at or after this
      *            position can be used for shaping context.
+     * @param contextStart the index of the start of the shaping context
+     * @param contextEnd the index of the end of the shaping context
      * @param x the x position at which to draw the text
      * @param y the y position at which to draw the text
      * @param isRtl whether the run is in RTL direction
      * @param paint the paint
-     * @hide
+     *
+     * @see #drawTextRun(char[], int, int, int, int, float, float, boolean, Paint)
      */
     public void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
             int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) {
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 649d996..20cd9b1 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -184,8 +184,12 @@
     /** @hide bit mask for the flag enabling vertical rendering for text */
     public static final int VERTICAL_TEXT_FLAG = 0x1000;
 
-    // we use this when we first create a paint
-    static final int DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG;
+
+    /** @hide default flags, even if unspecified */
+    public static final int HIDDEN_DEFAULT_PAINT_FLAGS =
+            DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG;
+    /** @hide default flags for no-param constructor */
+    public static final int DEFAULT_PAINT_FLAGS = ANTI_ALIAS_FLAG;
 
     /**
      * Font hinter option that disables font hinting.
@@ -415,9 +419,11 @@
 
     /**
      * Create a new paint with default settings.
+     *
+     * As of {@link android.os.Build.VERSION_CODES#MNC}, sets {@link #ANTI_ALIAS_FLAG}.
      */
     public Paint() {
-        this(0);
+        this(DEFAULT_PAINT_FLAGS);
     }
 
     /**
@@ -428,7 +434,7 @@
      */
     public Paint(int flags) {
         mNativePaint = native_init();
-        setFlags(flags | DEFAULT_PAINT_FLAGS);
+        setFlags(flags | HIDDEN_DEFAULT_PAINT_FLAGS);
         // TODO: Turning off hinting has undesirable side effects, we need to
         //       revisit hinting once we add support for subpixel positioning
         // setHinting(DisplayMetrics.DENSITY_DEVICE >= DisplayMetrics.DENSITY_TV
@@ -452,7 +458,7 @@
     /** Restores the paint to its default settings. */
     public void reset() {
         native_reset(mNativePaint);
-        setFlags(DEFAULT_PAINT_FLAGS);
+        setFlags(DEFAULT_PAINT_FLAGS | HIDDEN_DEFAULT_PAINT_FLAGS);
 
         // TODO: Turning off hinting has undesirable side effects, we need to
         //       revisit hinting once we add support for subpixel positioning
@@ -1870,7 +1876,7 @@
      * Convenience overload that takes a char array instead of a
      * String.
      *
-     * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int)
+     * @see #getTextRunAdvances(String, int, int, int, int, boolean, float[], int)
      * @hide
      */
     public float getTextRunAdvances(char[] chars, int index, int count,
@@ -1915,7 +1921,7 @@
      * Convenience overload that takes a CharSequence instead of a
      * String.
      *
-     * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int)
+     * @see #getTextRunAdvances(String, int, int, int, int, boolean, float[], int)
      * @hide
      */
     public float getTextRunAdvances(CharSequence text, int start, int end,
@@ -2257,10 +2263,10 @@
      * the input is a pair of regional indicator symbols, determine whether there is an emoji flag
      * for the pair.
      *
-     * Finally, if the string contains a variation selector, the method only returns true if
+     * <p>Finally, if the string contains a variation selector, the method only returns true if
      * the fonts contains a glyph specific to that variation.
      *
-     * Checking is done on the entire fallback chain, not just the immediate font referenced.
+     * <p>Checking is done on the entire fallback chain, not just the immediate font referenced.
      *
      * @param string the string to test whether there is glyph support
      * @return true if the typeface has a glyph for the string
@@ -2277,20 +2283,20 @@
      * purpose of complex text shaping, such as Arabic text potentially shaped differently based on
      * the text next to it.
      *
-     * All text outside the range {@code contextStart..contextEnd} is ignored. The text between
+     * <p>All text outside the range {@code contextStart..contextEnd} is ignored. The text between
      * {@code start} and {@code end} will be laid out to be measured.
      *
-     * The returned width measurement is the advance from {@code start} to {@code offset}. It is
+     * <p>The returned width measurement is the advance from {@code start} to {@code offset}. It is
      * generally a positive value, no matter the direction of the run. If {@code offset == end},
      * the return value is simply the width of the whole run from {@code start} to {@code end}.
      *
-     * Ligatures are formed for characters in the range {@code start..end} (but not for
+     * <p>Ligatures are formed for characters in the range {@code start..end} (but not for
      * {@code start..contextStart} or {@code end..contextEnd}). If {@code offset} points to a
      * character in the middle of such a formed ligature, but at a grapheme cluster boundary, the
      * return value will also reflect an advance in the middle of the ligature. See
      * {@link #getOffsetForAdvance} for more discussion of grapheme cluster boundaries.
      *
-     * The direction of the run is explicitly specified by {@code isRtl}. Thus, this method is
+     * <p>The direction of the run is explicitly specified by {@code isRtl}. Thus, this method is
      * suitable only for runs of a single direction.
      *
      * <p>All indices are relative to the start of {@code text}. Further, {@code 0 <= contextStart
@@ -2300,7 +2306,7 @@
      * @param start the index of the start of the range to measure
      * @param end the index + 1 of the end of the range to measure
      * @param contextStart the index of the start of the shaping context
-     * @param contextEnd the index + 1 of the end of the range to measure
+     * @param contextEnd the index + 1 of the end of the shaping context
      * @param isRtl whether the run is in RTL direction
      * @param offset index of caret position
      * @return width measurement between start and offset
@@ -2330,7 +2336,7 @@
      * @param start the index of the start of the range to measure
      * @param end the index + 1 of the end of the range to measure
      * @param contextStart the index of the start of the shaping context
-     * @param contextEnd the index + 1 of the end of the range to measure
+     * @param contextEnd the index + 1 of the end of the shaping context
      * @param isRtl whether the run is in RTL direction
      * @param offset index of caret position
      * @return width measurement between start and offset
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 4c2817c..dc9aa67 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -133,7 +133,7 @@
 
     private GradientState mGradientState;
 
-    private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+    private final Paint mFillPaint = new Paint();
     private Rect mPadding;
     private Paint mStrokePaint;   // optional, set by the caller
     private ColorFilter mColorFilter;   // optional, set by the caller
@@ -323,7 +323,7 @@
 
     private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) {
         if (mStrokePaint == null)  {
-            mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mStrokePaint = new Paint();
             mStrokePaint.setStyle(Paint.Style.STROKE);
         }
         mStrokePaint.setStrokeWidth(width);
@@ -1802,7 +1802,7 @@
         mPadding = state.mPadding;
 
         if (state.mStrokeWidth >= 0) {
-            mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+            mStrokePaint = new Paint();
             mStrokePaint.setStyle(Paint.Style.STROKE);
             mStrokePaint.setStrokeWidth(state.mStrokeWidth);
 
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 3bbbc71..c3d8cfa 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1464,7 +1464,8 @@
                     bounds.right - insetR - padR, bounds.bottom - r.mInsetB - padB);
 
             // Apply resolved gravity to drawable based on resolved size.
-            final int gravity = resolveGravity(r.mGravity, r.mWidth, r.mHeight);
+            final int gravity = resolveGravity(r.mGravity, r.mWidth, r.mHeight,
+                    d.getIntrinsicWidth(), d.getIntrinsicHeight());
             final int w = r.mWidth < 0 ? d.getIntrinsicWidth() : r.mWidth;
             final int h = r.mHeight < 0 ? d.getIntrinsicHeight() : r.mHeight;
             Gravity.apply(gravity, w, h, container, outRect, layoutDirection);
@@ -1491,7 +1492,8 @@
      * @param height height of the layer if set, -1 otherwise
      * @return the default gravity for the layer
      */
-    private static int resolveGravity(int gravity, int width, int height) {
+    private static int resolveGravity(int gravity, int width, int height,
+            int intrinsicWidth, int intrinsicHeight) {
         if (!Gravity.isHorizontal(gravity)) {
             if (width < 0) {
                 gravity |= Gravity.FILL_HORIZONTAL;
@@ -1508,6 +1510,17 @@
             }
         }
 
+        // If a dimension if not specified, either implicitly or explicitly,
+        // force FILL for that dimension's gravity. This ensures that colors
+        // are handled correctly and ensures backward compatibility.
+        if (width < 0 && intrinsicWidth < 0) {
+            gravity |= Gravity.FILL_HORIZONTAL;
+        }
+
+        if (height < 0 && intrinsicHeight < 0) {
+            gravity |= Gravity.FILL_VERTICAL;
+        }
+
         return gravity;
     }
 
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 334b3bd..caa0787 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -501,7 +501,7 @@
             if (mShapeState.mPaint != null) {
                 mShapeState.mPaint = new Paint(mShapeState.mPaint);
             } else {
-                mShapeState.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+                mShapeState.mPaint = new Paint();
             }
             if (mShapeState.mPadding != null) {
                 mShapeState.mPadding = new Rect(mShapeState.mPadding);
@@ -555,7 +555,7 @@
                 mAlpha = orig.mAlpha;
                 mShaderFactory = orig.mShaderFactory;
             } else {
-                mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+                mPaint = new Paint();
             }
         }
 
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index c259c25..ed91d70 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -529,27 +529,10 @@
                 KeymasterUtils.getKeymasterPaddingsFromJcaSignaturePaddings(
                         params.getSignaturePaddings()));
         args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
-        if (params.getUserAuthenticators() == 0) {
-            args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-        } else {
-            args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
-                    KeyStoreKeyProperties.UserAuthenticator.allToKeymaster(
-                            params.getUserAuthenticators()));
-            long secureUserId = GateKeeper.getSecureUserId();
-            if (secureUserId == 0) {
-                throw new IllegalStateException("Secure lock screen must be enabled"
-                        + " to import keys requiring user authentication");
-            }
-            args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, secureUserId);
-        }
-        if (params.isInvalidatedOnNewFingerprintEnrolled()) {
-            // TODO: Add the invalidate on fingerprint enrolled constraint once Keymaster supports
-            // that.
-        }
-        if (params.getUserAuthenticationValidityDurationSeconds() != -1) {
-            args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
-                    params.getUserAuthenticationValidityDurationSeconds());
-        }
+        KeymasterUtils.addUserAuthArgs(args,
+                params.getContext(),
+                params.isUserAuthenticationRequired(),
+                params.getUserAuthenticationValidityDurationSeconds());
         args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
                 (params.getKeyValidityStart() != null)
                         ? params.getKeyValidityStart() : new Date(0));
diff --git a/keystore/java/android/security/KeyGeneratorSpec.java b/keystore/java/android/security/KeyGeneratorSpec.java
index 7ecc47e..8f135a6 100644
--- a/keystore/java/android/security/KeyGeneratorSpec.java
+++ b/keystore/java/android/security/KeyGeneratorSpec.java
@@ -51,9 +51,8 @@
     private final String[] mEncryptionPaddings;
     private final String[] mBlockModes;
     private final boolean mRandomizedEncryptionRequired;
-    private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
+    private final boolean mUserAuthenticationRequired;
     private final int mUserAuthenticationValidityDurationSeconds;
-    private final boolean mInvalidatedOnNewFingerprintEnrolled;
 
     private KeyGeneratorSpec(
             Context context,
@@ -67,9 +66,8 @@
             String[] encryptionPaddings,
             String[] blockModes,
             boolean randomizedEncryptionRequired,
-            @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
-            int userAuthenticationValidityDurationSeconds,
-            boolean invalidatedOnNewFingerprintEnrolled) {
+            boolean userAuthenticationRequired,
+            int userAuthenticationValidityDurationSeconds) {
         if (context == null) {
             throw new IllegalArgumentException("context == null");
         } else if (TextUtils.isEmpty(keyStoreAlias)) {
@@ -92,9 +90,8 @@
                 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
         mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
         mRandomizedEncryptionRequired = randomizedEncryptionRequired;
-        mUserAuthenticators = userAuthenticators;
+        mUserAuthenticationRequired = userAuthenticationRequired;
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
-        mInvalidatedOnNewFingerprintEnrolled = invalidatedOnNewFingerprintEnrolled;
     }
 
     /**
@@ -188,18 +185,17 @@
     }
 
     /**
-     * Gets the set of user authenticators which protect access to this key. The key can only be
-     * used iff the user has authenticated to at least one of these user authenticators.
+     * Returns {@code true} if user authentication is required for this key to be used.
      *
-     * @return user authenticators or {@code 0} if the key can be used without user authentication.
+     * @see #getUserAuthenticationValidityDurationSeconds()
      */
-    public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
-        return mUserAuthenticators;
+    public boolean isUserAuthenticationRequired() {
+        return mUserAuthenticationRequired;
     }
 
     /**
-     * Gets the duration of time (seconds) for which this key can be used after the user
-     * successfully authenticates to one of the associated user authenticators.
+     * Gets the duration of time (seconds) for which this key can be used after the user is
+     * successfully authenticated.
      *
      * @return duration in seconds or {@code -1} if not restricted. {@code 0} means authentication
      *         is required for every use of the key.
@@ -209,17 +205,6 @@
     }
 
     /**
-     * Returns {@code true} if this key must be permanently invalidated once a new fingerprint is
-     * enrolled. This constraint only has effect if fingerprint reader is one of the user
-     * authenticators protecting access to this key.
-     *
-     * @see #getUserAuthenticators()
-     */
-    public boolean isInvalidatedOnNewFingerprintEnrolled() {
-        return mInvalidatedOnNewFingerprintEnrolled;
-    }
-
-    /**
      * Returns {@code true} if the key must be encrypted in the {@link java.security.KeyStore}.
      */
     public boolean isEncryptionRequired() {
@@ -238,9 +223,8 @@
         private String[] mEncryptionPaddings;
         private String[] mBlockModes;
         private boolean mRandomizedEncryptionRequired = true;
-        private @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
+        private boolean mUserAuthenticationRequired;
         private int mUserAuthenticationValidityDurationSeconds = -1;
-        private boolean mInvalidatedOnNewFingerprintEnrolled;
 
         /**
          * Creates a new instance of the {@code Builder} with the given {@code context}. The
@@ -416,32 +400,35 @@
         }
 
         /**
-         * Sets the user authenticators which protect access to this key. The key can only be used
-         * iff the user has authenticated to at least one of these user authenticators.
+         * Sets whether user authentication is required to use this key.
          *
          * <p>By default, the key can be used without user authentication.
          *
-         * @param userAuthenticators user authenticators or empty list if this key can be accessed
-         *        without user authentication.
+         * <p>When user authentication is required, the user authorizes the use of the key by
+         * authenticating to this Android device using a subset of their secure lock screen
+         * credentials. Different authentication methods are used depending on whether the every
+         * use of the key must be authenticated (as specified by
+         * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+         * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
+         * information</a>.
          *
          * @see #setUserAuthenticationValidityDurationSeconds(int)
          */
-        public Builder setUserAuthenticators(
-                @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators) {
-            mUserAuthenticators = userAuthenticators;
+        public Builder setUserAuthenticationRequired(boolean required) {
+            mUserAuthenticationRequired = required;
             return this;
         }
 
         /**
-         * Sets the duration of time (seconds) for which this key can be used after the user
-         * successfully authenticates to one of the associated user authenticators.
+         * Sets the duration of time (seconds) for which this key can be used after the user is
+         * successfully authenticated. This has effect only if user authentication is required.
          *
          * <p>By default, the user needs to authenticate for every use of the key.
          *
          * @param seconds duration in seconds or {@code 0} if the user needs to authenticate for
          *        every use of the key.
          *
-         * @see #setUserAuthenticators(int)
+         * @see #setUserAuthenticationRequired(boolean)
          */
         public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
             mUserAuthenticationValidityDurationSeconds = seconds;
@@ -449,20 +436,6 @@
         }
 
         /**
-         * Sets whether this key must be invalidated (permanently) once a new fingerprint is
-         * enrolled. This only has effect if fingerprint reader is one of the user authenticators
-         * protecting access to the key.
-         *
-         * <p>By default, enrolling a new fingerprint does not invalidate the key.
-         *
-         * @see #setUserAuthenticators(Set)
-         */
-        public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
-            mInvalidatedOnNewFingerprintEnrolled = invalidated;
-            return this;
-        }
-
-        /**
          * Builds a new instance instance of {@code KeyGeneratorSpec}.
          *
          * @throws IllegalArgumentException if a required field is missing or violates a constraint.
@@ -479,9 +452,8 @@
                     mEncryptionPaddings,
                     mBlockModes,
                     mRandomizedEncryptionRequired,
-                    mUserAuthenticators,
-                    mUserAuthenticationValidityDurationSeconds,
-                    mInvalidatedOnNewFingerprintEnrolled);
+                    mUserAuthenticationRequired,
+                    mUserAuthenticationValidityDurationSeconds);
         }
     }
 }
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index 5e5cf37..d6d3789 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -95,12 +95,10 @@
 
     private final boolean mRandomizedEncryptionRequired;
 
-    private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
+    private final boolean mUserAuthenticationRequired;
 
     private final int mUserAuthenticationValidityDurationSeconds;
 
-    private final boolean mInvalidatedOnNewFingerprintEnrolled;
-
     /**
      * Parameter specification for the "{@code AndroidKeyPairGenerator}"
      * instance of the {@link java.security.KeyPairGenerator} API. The
@@ -145,9 +143,8 @@
             String[] signaturePaddings,
             String[] blockModes,
             boolean randomizedEncryptionRequired,
-            @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
-            int userAuthenticationValidityDurationSeconds,
-            boolean invalidatedOnNewFingerprintEnrolled) {
+            boolean userAuthenticationRequired,
+            int userAuthenticationValidityDurationSeconds) {
         if (context == null) {
             throw new IllegalArgumentException("context == null");
         } else if (TextUtils.isEmpty(keyStoreAlias)) {
@@ -195,9 +192,8 @@
         mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
         mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
         mRandomizedEncryptionRequired = randomizedEncryptionRequired;
-        mUserAuthenticators = userAuthenticators;
+        mUserAuthenticationRequired = userAuthenticationRequired;
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
-        mInvalidatedOnNewFingerprintEnrolled = invalidatedOnNewFingerprintEnrolled;
     }
 
     /**
@@ -227,9 +223,8 @@
                 null, // signature paddings
                 null, // block modes
                 false, // randomized encryption required
-                0, // user authenticators
-                -1, // user authentication validity duration (seconds)
-                false // invalidate on new fingerprint enrolled
+                false, // user authentication required
+                -1 // user authentication validity duration (seconds)
                 );
     }
 
@@ -396,44 +391,34 @@
     }
 
     /**
-     * Gets the set of user authenticators which protect access to the private key. The key can only
-     * be used iff the user has authenticated to at least one of these user authenticators.
+     * Returns {@code true} if user authentication is required for this key to be used.
      *
      * <p>This restriction applies only to private key operations. Public key operations are not
      * restricted.
      *
-     * @return user authenticators or {@code 0} if the key can be used without user authentication.
+     * @see #getUserAuthenticationValidityDurationSeconds()
      */
-    public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
-        return mUserAuthenticators;
+    public boolean isUserAuthenticationRequired() {
+        return mUserAuthenticationRequired;
     }
 
     /**
      * Gets the duration of time (seconds) for which the private key can be used after the user
-     * successfully authenticates to one of the associated user authenticators.
+     * is successfully authenticated.
      *
      * <p>This restriction applies only to private key operations. Public key operations are not
      * restricted.
      *
      * @return duration in seconds or {@code -1} if not restricted. {@code 0} means authentication
      *         is required for every use of the key.
+     *
+     * @see #isUserAuthenticationRequired()
      */
     public int getUserAuthenticationValidityDurationSeconds() {
         return mUserAuthenticationValidityDurationSeconds;
     }
 
     /**
-     * Returns {@code true} if this key must be permanently invalidated once a new fingerprint is
-     * enrolled. This constraint only has effect if fingerprint reader is one of the user
-     * authenticators protecting access to this key.
-     *
-     * @see #getUserAuthenticators()
-     */
-    public boolean isInvalidatedOnNewFingerprintEnrolled() {
-        return mInvalidatedOnNewFingerprintEnrolled;
-    }
-
-    /**
      * Builder class for {@link KeyPairGeneratorSpec} objects.
      * <p>
      * This will build a parameter spec for use with the <a href="{@docRoot}
@@ -493,12 +478,10 @@
 
         private boolean mRandomizedEncryptionRequired = true;
 
-        private @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
+        private boolean mUserAuthenticationRequired;
 
         private int mUserAuthenticationValidityDurationSeconds = -1;
 
-        private boolean mInvalidatedOnNewFingerprintEnrolled;
-
         /**
          * Creates a new instance of the {@code Builder} with the given
          * {@code context}. The {@code context} passed in may be used to pop up
@@ -774,28 +757,31 @@
         }
 
         /**
-         * Sets the user authenticators which protect access to this key. The key can only be used
-         * iff the user has authenticated to at least one of these user authenticators.
+         * Sets whether user authentication is required to use this key.
          *
          * <p>By default, the key can be used without user authentication.
          *
+         * <p>When user authentication is required, the user authorizes the use of the key by
+         * authenticating to this Android device using a subset of their secure lock screen
+         * credentials. Different authentication methods are used depending on whether the every
+         * use of the key must be authenticated (as specified by
+         * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+         * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
+         * information</a>.
+         *
          * <p>This restriction applies only to private key operations. Public key operations are not
          * restricted.
          *
-         * @param userAuthenticators user authenticators or {@code 0} if this key can be accessed
-         *        without user authentication.
-         *
          * @see #setUserAuthenticationValidityDurationSeconds(int)
          */
-        public Builder setUserAuthenticators(
-                @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators) {
-            mUserAuthenticators = userAuthenticators;
+        public Builder setUserAuthenticationRequired(boolean required) {
+            mUserAuthenticationRequired = required;
             return this;
         }
 
         /**
-         * Sets the duration of time (seconds) for which this key can be used after the user
-         * successfully authenticates to one of the associated user authenticators.
+         * Sets the duration of time (seconds) for which this key can be used after the user is
+         * successfully authenticated. This has effect only if user authentication is required.
          *
          * <p>By default, the user needs to authenticate for every use of the key.
          *
@@ -805,7 +791,7 @@
          * @param seconds duration in seconds or {@code 0} if the user needs to authenticate for
          *        every use of the key.
          *
-         * @see #setUserAuthenticators(int)
+         * @see #setUserAuthenticationRequired(boolean)
          */
         public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
             mUserAuthenticationValidityDurationSeconds = seconds;
@@ -813,20 +799,6 @@
         }
 
         /**
-         * Sets whether this key must be invalidated (permanently) once a new fingerprint is
-         * enrolled. This only has effect if fingerprint reader is one of the user authenticators
-         * protecting access to the key.
-         *
-         * <p>By default, enrolling a new fingerprint does not invalidate the key.
-         *
-         * @see #setUserAuthenticators(Set)
-         */
-        public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
-            mInvalidatedOnNewFingerprintEnrolled = invalidated;
-            return this;
-        }
-
-        /**
          * Builds the instance of the {@code KeyPairGeneratorSpec}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -852,9 +824,8 @@
                     mSignaturePaddings,
                     mBlockModes,
                     mRandomizedEncryptionRequired,
-                    mUserAuthenticators,
-                    mUserAuthenticationValidityDurationSeconds,
-                    mInvalidatedOnNewFingerprintEnrolled);
+                    mUserAuthenticationRequired,
+                    mUserAuthenticationValidityDurationSeconds);
         }
     }
 }
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 293c4c9..20f6042 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -161,27 +161,10 @@
                 KeymasterDefs.KM_TAG_PADDING,
                 KeymasterUtils.getKeymasterPaddingsFromJcaEncryptionPaddings(
                         spec.getEncryptionPaddings()));
-        if (spec.getUserAuthenticators() == 0) {
-            args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-        } else {
-            args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
-                    KeyStoreKeyProperties.UserAuthenticator.allToKeymaster(
-                            spec.getUserAuthenticators()));
-            long secureUserId = GateKeeper.getSecureUserId();
-            if (secureUserId == 0) {
-                throw new IllegalStateException("Secure lock screen must be enabled"
-                        + " to generate keys requiring user authentication");
-            }
-            args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, secureUserId);
-        }
-        if (spec.isInvalidatedOnNewFingerprintEnrolled()) {
-            // TODO: Add the invalidate on fingerprint enrolled constraint once Keymaster supports
-            // that.
-        }
-        if (spec.getUserAuthenticationValidityDurationSeconds() != -1) {
-            args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
-                    spec.getUserAuthenticationValidityDurationSeconds());
-        }
+        KeymasterUtils.addUserAuthArgs(args,
+                spec.getContext(),
+                spec.isUserAuthenticationRequired(),
+                spec.getUserAuthenticationValidityDurationSeconds());
         args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
                 (spec.getKeyValidityStart() != null)
                 ? spec.getKeyValidityStart() : new Date(0));
diff --git a/keystore/java/android/security/KeyStoreKeyProperties.java b/keystore/java/android/security/KeyStoreKeyProperties.java
index 206103f..b85ec53 100644
--- a/keystore/java/android/security/KeyStoreKeyProperties.java
+++ b/keystore/java/android/security/KeyStoreKeyProperties.java
@@ -122,101 +122,6 @@
     }
 
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true,
-            value = {UserAuthenticator.LOCK_SCREEN, UserAuthenticator.FINGERPRINT_READER})
-    public @interface UserAuthenticatorEnum {}
-
-    /**
-     * User authenticators which can be used to restrict/protect access to keys.
-     */
-    public static abstract class UserAuthenticator {
-        private UserAuthenticator() {}
-
-        /** Lock screen. */
-        public static final int LOCK_SCREEN = 1 << 0;
-
-        /** Fingerprint reader/sensor. */
-        public static final int FINGERPRINT_READER = 1 << 1;
-
-        /**
-         * @hide
-         */
-        public static int toKeymaster(@UserAuthenticatorEnum int userAuthenticator) {
-            switch (userAuthenticator) {
-                case LOCK_SCREEN:
-                    return KeymasterDefs.HW_AUTH_PASSWORD;
-                case FINGERPRINT_READER:
-                    return KeymasterDefs.HW_AUTH_FINGERPRINT;
-                default:
-                    throw new IllegalArgumentException(
-                            "Unknown user authenticator: " + userAuthenticator);
-            }
-        }
-
-        /**
-         * @hide
-         */
-        public static @UserAuthenticatorEnum int fromKeymaster(int userAuthenticator) {
-            switch (userAuthenticator) {
-                case KeymasterDefs.HW_AUTH_PASSWORD:
-                    return LOCK_SCREEN;
-                case KeymasterDefs.HW_AUTH_FINGERPRINT:
-                    return FINGERPRINT_READER;
-                default:
-                    throw new IllegalArgumentException(
-                            "Unknown user authenticator: " + userAuthenticator);
-            }
-        }
-
-        /**
-         * @hide
-         */
-        public static int allToKeymaster(@UserAuthenticatorEnum int userAuthenticators) {
-            int result = 0;
-            int userAuthenticator = 1;
-            while (userAuthenticators != 0) {
-                if ((userAuthenticators & 1) != 0) {
-                    result |= toKeymaster(userAuthenticator);
-                }
-                userAuthenticators >>>= 1;
-                userAuthenticator <<= 1;
-            }
-            return result;
-        }
-
-        /**
-         * @hide
-         */
-        public static @UserAuthenticatorEnum int allFromKeymaster(int userAuthenticators) {
-            @UserAuthenticatorEnum int result = 0;
-            int userAuthenticator = 1;
-            while (userAuthenticators != 0) {
-                if ((userAuthenticators & 1) != 0) {
-                    result |= fromKeymaster(userAuthenticator);
-                }
-                userAuthenticators >>>= 1;
-                userAuthenticator <<= 1;
-            }
-            return result;
-        }
-
-        /**
-         * @hide
-         */
-        public static String toString(@UserAuthenticatorEnum int userAuthenticator) {
-            switch (userAuthenticator) {
-                case LOCK_SCREEN:
-                    return "LOCK_SCREEN";
-                case FINGERPRINT_READER:
-                    return "FINGERPRINT_READER";
-                default:
-                    throw new IllegalArgumentException(
-                            "Unknown user authenticator: " + userAuthenticator);
-            }
-        }
-    }
-
-    @Retention(RetentionPolicy.SOURCE)
     @IntDef({Origin.GENERATED, Origin.IMPORTED, Origin.UNKNOWN})
     public @interface OriginEnum {}
 
diff --git a/keystore/java/android/security/KeyStoreKeySpec.java b/keystore/java/android/security/KeyStoreKeySpec.java
index a89e4dd..96d58d8 100644
--- a/keystore/java/android/security/KeyStoreKeySpec.java
+++ b/keystore/java/android/security/KeyStoreKeySpec.java
@@ -36,10 +36,9 @@
     private final String[] mSignaturePaddings;
     private final String[] mDigests;
     private final String[] mBlockModes;
-    private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
-    private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mTeeEnforcedUserAuthenticators;
+    private final boolean mUserAuthenticationRequired;
     private final int mUserAuthenticationValidityDurationSeconds;
-    private final boolean mInvalidatedOnNewFingerprintEnrolled;
+    private final boolean mUserAuthenticationRequirementTeeEnforced;
 
     /**
      * @hide
@@ -56,10 +55,9 @@
             String[] signaturePaddings,
             String[] digests,
             String[] blockModes,
-            @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
-            @KeyStoreKeyProperties.UserAuthenticatorEnum int teeEnforcedUserAuthenticators,
+            boolean userAuthenticationRequired,
             int userAuthenticationValidityDurationSeconds,
-            boolean invalidatedOnNewFingerprintEnrolled) {
+            boolean userAuthenticationRequirementTeeEnforced) {
         mKeystoreAlias = keystoreKeyAlias;
         mTeeBacked = teeBacked;
         mOrigin = origin;
@@ -74,10 +72,9 @@
                 ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
         mDigests = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(digests));
         mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
-        mUserAuthenticators = userAuthenticators;
-        mTeeEnforcedUserAuthenticators = teeEnforcedUserAuthenticators;
+        mUserAuthenticationRequired = userAuthenticationRequired;
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
-        mInvalidatedOnNewFingerprintEnrolled = invalidatedOnNewFingerprintEnrolled;
+        mUserAuthenticationRequirementTeeEnforced = userAuthenticationRequirementTeeEnforced;
     }
 
     /**
@@ -172,43 +169,34 @@
     }
 
     /**
-     * Gets the set of user authenticators which protect access to the key. The key can only be used
-     * iff the user has authenticated to at least one of these user authenticators.
+     * Returns {@code true} if user authentication is required for this key to be used.
      *
-     * @return user authenticators or {@code 0} if the key can be used without user authentication.
+     * @see #getUserAuthenticationValidityDurationSeconds()
      */
-    public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
-        return mUserAuthenticators;
+    public boolean isUserAuthenticationRequired() {
+        return mUserAuthenticationRequired;
     }
 
     /**
-     * Gets the set of user authenticators for which the TEE enforces access restrictions for this
-     * key. This is a subset of the user authentications returned by
-     * {@link #getUserAuthenticators()}.
-     */
-    public @KeyStoreKeyProperties.UserAuthenticatorEnum int getTeeEnforcedUserAuthenticators() {
-        return mTeeEnforcedUserAuthenticators;
-    }
-
-    /**
-     * Gets the duration of time (seconds) for which the key can be used after the user
-     * successfully authenticates to one of the associated user authenticators.
+     * Gets the duration of time (seconds) for which this key can be used after the user is
+     * successfully authenticated.
      *
      * @return duration in seconds or {@code -1} if not restricted. {@code 0} means authentication
      *         is required for every use of the key.
+     *
+     * @see #isUserAuthenticationRequired()
      */
     public int getUserAuthenticationValidityDurationSeconds() {
         return mUserAuthenticationValidityDurationSeconds;
     }
 
     /**
-     * Returns {@code true} if this key will be permanently invalidated once a new fingerprint is
-     * enrolled. This constraint only has effect if fingerprint reader is one of the user
-     * authenticators protecting access to this key.
+     * Returns {@code true} if the requirement that this key can only be used if the user has been
+     * authenticated if enforced by the TEE.
      *
-     * @see #getUserAuthenticators()
+     * @see #isUserAuthenticationRequired()
      */
-    public boolean isInvalidatedOnNewFingerprintEnrolled() {
-        return mInvalidatedOnNewFingerprintEnrolled;
+    public boolean isUserAuthenticationRequirementTeeEnforced() {
+        return mUserAuthenticationRequirementTeeEnforced;
     }
 }
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index c24b74f..b4747e9 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -39,7 +39,8 @@
  * {@code KeyStore}.
  */
 public final class KeyStoreParameter implements ProtectionParameter {
-    private int mFlags;
+    private final Context mContext;
+    private final int mFlags;
     private final Date mKeyValidityStart;
     private final Date mKeyValidityForOriginationEnd;
     private final Date mKeyValidityForConsumptionEnd;
@@ -49,11 +50,12 @@
     private final String[] mDigests;
     private final String[] mBlockModes;
     private final boolean mRandomizedEncryptionRequired;
-    private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
+    private final boolean mUserAuthenticationRequired;
     private final int mUserAuthenticationValidityDurationSeconds;
-    private final boolean mInvalidatedOnNewFingerprintEnrolled;
 
-    private KeyStoreParameter(int flags,
+    private KeyStoreParameter(
+            Context context,
+            int flags,
             Date keyValidityStart,
             Date keyValidityForOriginationEnd,
             Date keyValidityForConsumptionEnd,
@@ -63,15 +65,17 @@
             String[] digests,
             String[] blockModes,
             boolean randomizedEncryptionRequired,
-            @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
-            int userAuthenticationValidityDurationSeconds,
-            boolean invalidatedOnNewFingerprintEnrolled) {
-        if ((userAuthenticationValidityDurationSeconds < 0)
+            boolean userAuthenticationRequired,
+            int userAuthenticationValidityDurationSeconds) {
+        if (context == null) {
+            throw new IllegalArgumentException("context == null");
+        } else if ((userAuthenticationValidityDurationSeconds < 0)
                 && (userAuthenticationValidityDurationSeconds != -1)) {
             throw new IllegalArgumentException(
                     "userAuthenticationValidityDurationSeconds must not be negative");
         }
 
+        mContext = context;
         mFlags = flags;
         mKeyValidityStart = keyValidityStart;
         mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
@@ -84,9 +88,15 @@
         mDigests = ArrayUtils.cloneIfNotEmpty(digests);
         mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
         mRandomizedEncryptionRequired = randomizedEncryptionRequired;
-        mUserAuthenticators = userAuthenticators;
+        mUserAuthenticationRequired = userAuthenticationRequired;
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
-        mInvalidatedOnNewFingerprintEnrolled = invalidatedOnNewFingerprintEnrolled;
+    }
+
+    /**
+     * Gets the Android context used for operations with this instance.
+     */
+    public Context getContext() {
+        return mContext;
     }
 
     /**
@@ -198,18 +208,17 @@
     }
 
     /**
-     * Gets the set of user authenticators which protect access to this key. The key can only be
-     * used iff the user has authenticated to at least one of these user authenticators.
+     * Returns {@code true} if user authentication is required for this key to be used.
      *
-     * @return user authenticators or {@code 0} if the key can be used without user authentication.
+     * @see #getUserAuthenticationValidityDurationSeconds()
      */
-    public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
-        return mUserAuthenticators;
+    public boolean isUserAuthenticationRequired() {
+        return mUserAuthenticationRequired;
     }
 
     /**
-     * Gets the duration of time (seconds) for which this key can be used after the user
-     * successfully authenticates to one of the associated user authenticators.
+     * Gets the duration of time (seconds) for which this key can be used after the user is
+     * successfully authenticated.
      *
      * @return duration in seconds or {@code -1} if not restricted. {@code 0} means authentication
      *         is required for every use of the key.
@@ -219,17 +228,6 @@
     }
 
     /**
-     * Returns {@code true} if this key must be permanently invalidated once a new fingerprint is
-     * enrolled. This constraint only has effect if fingerprint reader is one of the user
-     * authenticators protecting access to this key.
-     *
-     * @see #getUserAuthenticators()
-     */
-    public boolean isInvalidatedOnNewFingerprintEnrolled() {
-        return mInvalidatedOnNewFingerprintEnrolled;
-    }
-
-    /**
      * Builder class for {@link KeyStoreParameter} objects.
      * <p>
      * This will build protection parameters for use with the
@@ -247,6 +245,7 @@
      * </pre>
      */
     public final static class Builder {
+        private final Context mContext;
         private int mFlags;
         private Date mKeyValidityStart;
         private Date mKeyValidityForOriginationEnd;
@@ -257,9 +256,8 @@
         private String[] mDigests;
         private String[] mBlockModes;
         private boolean mRandomizedEncryptionRequired = true;
-        private @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
+        private boolean mUserAuthenticationRequired;
         private int mUserAuthenticationValidityDurationSeconds = -1;
-        private boolean mInvalidatedOnNewFingerprintEnrolled;
 
         /**
          * Creates a new instance of the {@code Builder} with the given
@@ -271,8 +269,7 @@
             if (context == null) {
                 throw new NullPointerException("context == null");
             }
-
-            // Context is currently not used, but will be in the future.
+            mContext = context;
         }
 
         /**
@@ -440,32 +437,35 @@
         }
 
         /**
-         * Sets the user authenticators which protect access to this key. The key can only be used
-         * iff the user has authenticated to at least one of these user authenticators.
+         * Sets whether user authentication is required to use this key.
          *
          * <p>By default, the key can be used without user authentication.
          *
-         * @param userAuthenticators user authenticators or {@code 0} if this key can be accessed
-         *        without user authentication.
+         * <p>When user authentication is required, the user authorizes the use of the key by
+         * authenticating to this Android device using a subset of their secure lock screen
+         * credentials. Different authentication methods are used depending on whether the every
+         * use of the key must be authenticated (as specified by
+         * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+         * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
+         * information</a>.
          *
          * @see #setUserAuthenticationValidityDurationSeconds(int)
          */
-        public Builder setUserAuthenticators(
-                @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators) {
-            mUserAuthenticators = userAuthenticators;
+        public Builder setUserAuthenticationRequired(boolean required) {
+            mUserAuthenticationRequired = required;
             return this;
         }
 
         /**
-         * Sets the duration of time (seconds) for which this key can be used after the user
-         * successfully authenticates to one of the associated user authenticators.
+         * Sets the duration of time (seconds) for which this key can be used after the user is
+         * successfully authenticated. This has effect only if user authentication is required.
          *
          * <p>By default, the user needs to authenticate for every use of the key.
          *
          * @param seconds duration in seconds or {@code 0} if the user needs to authenticate for
          *        every use of the key.
          *
-         * @see #setUserAuthenticators(int)
+         * @see #setUserAuthenticationRequired(boolean)
          */
         public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
             mUserAuthenticationValidityDurationSeconds = seconds;
@@ -473,27 +473,15 @@
         }
 
         /**
-         * Sets whether this key must be invalidated (permanently) whenever a new fingerprint is
-         * enrolled. This only has effect if fingerprint reader is one of the user authenticators
-         * protecting access to the key.
-         *
-         * <p>By default, enrolling a new fingerprint does not invalidate the key.
-         *
-         * @see #setUserAuthenticators(Set)
-         */
-        public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
-            mInvalidatedOnNewFingerprintEnrolled = invalidated;
-            return this;
-        }
-
-        /**
          * Builds the instance of the {@code KeyStoreParameter}.
          *
          * @throws IllegalArgumentException if a required field is missing
          * @return built instance of {@code KeyStoreParameter}
          */
         public KeyStoreParameter build() {
-            return new KeyStoreParameter(mFlags,
+            return new KeyStoreParameter(
+                    mContext,
+                    mFlags,
                     mKeyValidityStart,
                     mKeyValidityForOriginationEnd,
                     mKeyValidityForConsumptionEnd,
@@ -503,9 +491,8 @@
                     mDigests,
                     mBlockModes,
                     mRandomizedEncryptionRequired,
-                    mUserAuthenticators,
-                    mUserAuthenticationValidityDurationSeconds,
-                    mInvalidatedOnNewFingerprintEnrolled);
+                    mUserAuthenticationRequired,
+                    mUserAuthenticationValidityDurationSeconds);
         }
     }
 }
diff --git a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
index 4be0638..bfe09e3 100644
--- a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
@@ -81,8 +81,8 @@
         String[] encryptionPaddings;
         String[] digests;
         String[] blockModes;
-        @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators;
-        @KeyStoreKeyProperties.UserAuthenticatorEnum int teeEnforcedUserAuthenticators;
+        int keymasterSwEnforcedUserAuthenticators;
+        int keymasterHwEnforcedUserAuthenticators;
         try {
             if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
                 teeBacked = true;
@@ -122,21 +122,10 @@
                     keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST));
             blockModes = KeymasterUtils.getJcaBlockModesFromKeymasterBlockModes(
                     keyCharacteristics.getInts(KeymasterDefs.KM_TAG_BLOCK_MODE));
-
-            @KeyStoreKeyProperties.UserAuthenticatorEnum
-            int swEnforcedKeymasterUserAuthenticators =
+            keymasterSwEnforcedUserAuthenticators =
                     keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
-            @KeyStoreKeyProperties.UserAuthenticatorEnum
-            int hwEnforcedKeymasterUserAuthenticators =
+            keymasterHwEnforcedUserAuthenticators =
                     keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
-            @KeyStoreKeyProperties.UserAuthenticatorEnum
-            int keymasterUserAuthenticators =
-                    swEnforcedKeymasterUserAuthenticators | hwEnforcedKeymasterUserAuthenticators;
-            userAuthenticators = KeyStoreKeyProperties.UserAuthenticator.allFromKeymaster(
-                    keymasterUserAuthenticators);
-            teeEnforcedUserAuthenticators =
-                    KeyStoreKeyProperties.UserAuthenticator.allFromKeymaster(
-                            hwEnforcedKeymasterUserAuthenticators);
         } catch (IllegalArgumentException e) {
             throw new InvalidKeySpecException("Unsupported key characteristic", e);
         }
@@ -157,11 +146,13 @@
                 && (keyValidityForConsumptionEnd.getTime() == Long.MAX_VALUE)) {
             keyValidityForConsumptionEnd = null;
         }
+        boolean userAuthenticationRequired =
+                !keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
         int userAuthenticationValidityDurationSeconds =
                 keyCharacteristics.getInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
-
-        // TODO: Populate the value below from key characteristics once Keymaster is ready.
-        boolean invalidatedOnNewFingerprintEnrolled = false;
+        boolean userAuthenticationRequirementEnforcedInTee = (userAuthenticationRequired)
+                && (keymasterHwEnforcedUserAuthenticators != 0)
+                && (keymasterSwEnforcedUserAuthenticators == 0);
 
         return new KeyStoreKeySpec(entryAlias,
                 teeBacked,
@@ -175,10 +166,9 @@
                 EmptyArray.STRING, // no signature paddings -- this is symmetric crypto
                 digests,
                 blockModes,
-                userAuthenticators,
-                teeEnforcedUserAuthenticators,
+                userAuthenticationRequired,
                 userAuthenticationValidityDurationSeconds,
-                invalidatedOnNewFingerprintEnrolled);
+                userAuthenticationRequirementEnforcedInTee);
     }
 
     @Override
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/KeymasterUtils.java
index 67f75c2..7bf5475 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/KeymasterUtils.java
@@ -16,7 +16,14 @@
 
 package android.security;
 
+import android.content.Context;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.security.keymaster.KeymasterArguments;
 import android.security.keymaster.KeymasterDefs;
+import android.service.gatekeeper.IGateKeeperService;
 
 import libcore.util.EmptyArray;
 
@@ -339,4 +346,72 @@
         }
         return result;
     }
+
+    private static long getRootSid() {
+        IGateKeeperService gatekeeperService = IGateKeeperService.Stub.asInterface(
+                ServiceManager.getService("android.service.gatekeeper.IGateKeeperService"));
+        if (gatekeeperService == null) {
+            throw new IllegalStateException("Gatekeeper service not available");
+        }
+
+        try {
+            return gatekeeperService.getSecureUserId(UserHandle.myUserId());
+        } catch (RemoteException e) {
+            throw new IllegalStateException("Failed to obtain root SID");
+        }
+    }
+
+    /**
+     * Adds keymaster arguments to express the key's authorization policy supported by user
+     * authentication.
+     *
+     * @param userAuthenticationRequired whether user authentication is required to authorize the
+     *        use of the key.
+     * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user
+     *        authentication is valid as authorization for using the key or {@code -1} if every
+     *        use of the key needs authorization.
+     */
+    public static void addUserAuthArgs(KeymasterArguments args,
+            Context context,
+            boolean userAuthenticationRequired,
+            int userAuthenticationValidityDurationSeconds) {
+        if (!userAuthenticationRequired) {
+            args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
+            return;
+        }
+
+        if (userAuthenticationValidityDurationSeconds == -1) {
+            // Every use of this key needs to be authorized by the user. This currently means
+            // fingerprint-only auth.
+            FingerprintManager fingerprintManager =
+                    context.getSystemService(FingerprintManager.class);
+            if ((fingerprintManager == null) || (!fingerprintManager.isHardwareDetected())) {
+                throw new IllegalStateException(
+                        "This device does not support keys which require authentication for every"
+                        + " use -- this requires fingerprint authentication which is not"
+                        + " available on this device");
+            }
+            long fingerprintOnlySid = fingerprintManager.getAuthenticatorId();
+            if (fingerprintOnlySid == 0) {
+                throw new IllegalStateException(
+                        "At least one fingerprint must be enrolled to create keys requiring user"
+                        + " authentication for every use");
+            }
+            args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, fingerprintOnlySid);
+            args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
+        } else {
+            // The key is authorized for use for the specified amount of time after the user has
+            // authenticated. Whatever unlocks the secure lock screen should authorize this key.
+            long rootSid = getRootSid();
+            if (rootSid == 0) {
+                throw new IllegalStateException("Secure lock screen must be enabled"
+                        + " to create keys requiring user authentication");
+            }
+            args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, rootSid);
+            args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
+                    KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
+            args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
+                    userAuthenticationValidityDurationSeconds);
+        }
+    }
 }
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 6b86030..a7784b6 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -88,8 +88,7 @@
 void DisplayListCanvas::resume() {
 }
 
-void DisplayListCanvas::callDrawGLFunction(Functor *functor, Rect& dirty) {
-    // Ignore dirty during recording, it matters only when we replay
+void DisplayListCanvas::callDrawGLFunction(Functor *functor) {
     addDrawOp(new (alloc()) DrawFunctorOp(functor));
     mDisplayListData->functors.add(functor);
 }
@@ -202,12 +201,12 @@
     return mState.clipRegion(region, op);
 }
 
-void DisplayListCanvas::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) {
+void DisplayListCanvas::drawRenderNode(RenderNode* renderNode) {
     LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
 
     // dirty is an out parameter and should not be recorded,
     // it matters only when replaying the display list
-    DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *mState.currentTransform());
+    DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, *mState.currentTransform());
     addRenderNodeOp(op);
 }
 
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 2b0b6b2..fa4b2b4 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -115,10 +115,10 @@
 // HWUI Canvas draw operations - special
 // ----------------------------------------------------------------------------
     void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
-    void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags);
+    void drawRenderNode(RenderNode* renderNode);
 
     // TODO: rename for consistency
-    void callDrawGLFunction(Functor* functor, Rect& dirty);
+    void callDrawGLFunction(Functor* functor);
 
     void setHighContrastText(bool highContrastText) {
         mHighContrastText = highContrastText;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index b5801fc..4863ed2 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1398,10 +1398,9 @@
     friend class RenderNode; // grant RenderNode access to info of child
     friend class DisplayListData; // grant DisplayListData access to info of child
 public:
-    DrawRenderNodeOp(RenderNode* renderNode, int flags, const mat4& transformFromParent)
+    DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent)
             : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr)
             , mRenderNode(renderNode)
-            , mFlags(flags)
             , mTransformFromParent(transformFromParent)
             , mSkipInOrderDraw(false) {}
 
@@ -1424,7 +1423,7 @@
     }
 
     virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw RenderNode %p %s, flags %#x", mRenderNode, mRenderNode->getName(), mFlags);
+        OP_LOG("Draw RenderNode %p %s, flags %#x", mRenderNode, mRenderNode->getName());
         if (mRenderNode && (logFlags & kOpLogFlag_Recurse)) {
             mRenderNode->output(level + 1);
         }
@@ -1436,7 +1435,6 @@
 
 private:
     RenderNode* mRenderNode;
-    const int mFlags;
 
     ///////////////////////////
     // Properties below are used by RenderNode::computeOrderingImpl() and issueOperations()
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index e009451..ac4c0d0 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -138,7 +138,7 @@
 }
 
 void RenderNode::prepareLayer(TreeInfo& info, uint32_t dirtyMask) {
-    LayerType layerType = properties().layerProperties().type();
+    LayerType layerType = properties().effectiveLayerType();
     if (CC_UNLIKELY(layerType == LayerType::RenderLayer)) {
         // Damage applied so far needs to affect our parent, but does not require
         // the layer to be updated. So we pop/push here to clear out the current
@@ -153,7 +153,7 @@
 }
 
 void RenderNode::pushLayerUpdate(TreeInfo& info) {
-    LayerType layerType = properties().layerProperties().type();
+    LayerType layerType = properties().effectiveLayerType();
     // If we are not a layer OR we cannot be rendered (eg, view was detached)
     // we need to destroy any Layers we may have had previously
     if (CC_LIKELY(layerType != LayerType::RenderLayer) || CC_UNLIKELY(!isRenderable())) {
@@ -384,33 +384,16 @@
             renderer.concatMatrix(*properties().getTransformMatrix());
         }
     }
-    const bool isLayer = properties().layerProperties().type() != LayerType::None;
+    const bool isLayer = properties().effectiveLayerType() != LayerType::None;
     int clipFlags = properties().getClippingFlags();
     if (properties().getAlpha() < 1) {
         if (isLayer) {
             clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer
 
             renderer.setOverrideLayerAlpha(properties().getAlpha());
-        } else if (!properties().getHasOverlappingRendering()) {
-            renderer.scaleAlpha(properties().getAlpha());
         } else {
-            Rect layerBounds(0, 0, getWidth(), getHeight());
-            int saveFlags = SkCanvas::kHasAlphaLayer_SaveFlag;
-            if (clipFlags) {
-                saveFlags |= SkCanvas::kClipToLayer_SaveFlag;
-                properties().getClippingRectForFlags(clipFlags, &layerBounds);
-                clipFlags = 0; // all clipping done by saveLayer
-            }
-
-            ATRACE_FORMAT("%s alpha caused %ssaveLayer %dx%d", getName(),
-                    (saveFlags & SkCanvas::kClipToLayer_SaveFlag) ? "" : "unclipped ",
-                    static_cast<int>(layerBounds.getWidth()),
-                    static_cast<int>(layerBounds.getHeight()));
-
-            SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
-                    layerBounds.left, layerBounds.top, layerBounds.right, layerBounds.bottom,
-                    properties().getAlpha() * 255, saveFlags);
-            handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
+            LOG_ALWAYS_FATAL_IF(properties().getHasOverlappingRendering());
+            renderer.scaleAlpha(properties().getAlpha());
         }
     }
     if (clipFlags) {
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index 9f1ceed..0ed3c47 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -144,27 +144,16 @@
         }
     }
 
-    const bool isLayer = layerProperties().type() != LayerType::None;
+    const bool isLayer = effectiveLayerType() != LayerType::None;
     int clipFlags = getClippingFlags();
     if (mPrimitiveFields.mAlpha < 1) {
         if (isLayer) {
             clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer
 
             ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha);
-        } else if (!mPrimitiveFields.mHasOverlappingRendering) {
-            ALOGD("%*sScaleAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha);
         } else {
-            Rect layerBounds(0, 0, getWidth(), getHeight());
-            int saveFlags = SkCanvas::kHasAlphaLayer_SaveFlag;
-            if (clipFlags) {
-                saveFlags |= SkCanvas::kClipToLayer_SaveFlag;
-                getClippingRectForFlags(clipFlags, &layerBounds);
-                clipFlags = 0; // all clipping done by saveLayer
-            }
-
-            ALOGD("%*sSaveLayerAlpha %d, %d, %d, %d, %d, 0x%x", level * 2, "",
-                    (int)layerBounds.left, (int)layerBounds.top, (int)layerBounds.right, (int)layerBounds.bottom,
-                    (int)(mPrimitiveFields.mAlpha * 255), saveFlags);
+            LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mHasOverlappingRendering);
+            ALOGD("%*sScaleAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha);
         }
     }
     if (clipFlags) {
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 61e98d2..a43566d 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -73,10 +73,6 @@
         return false;
     }
 
-    LayerType type() const {
-        return mType;
-    }
-
     bool setOpaque(bool opaque) {
         return RP_SET(mOpaque, opaque);
     }
@@ -122,6 +118,11 @@
     ~LayerProperties();
     void reset();
 
+    // Private since external users should go through properties().effectiveLayerType()
+    LayerType type() const {
+        return mType;
+    }
+
     friend class RenderProperties;
 
     LayerType mType = LayerType::None;
@@ -575,6 +576,17 @@
                 && getOutline().getAlpha() != 0.0f;
     }
 
+    LayerType effectiveLayerType() const {
+        LayerType type = mLayerProperties.mType;
+        if (type == LayerType::None
+                && !MathUtils::isZero(mPrimitiveFields.mAlpha)
+                && mPrimitiveFields.mAlpha < 1
+                && mPrimitiveFields.mHasOverlappingRendering) {
+            return LayerType::RenderLayer;
+        }
+        return type;
+    }
+
 private:
     // Rendering properties
     struct PrimitiveFields {
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index 61ad082..62782af 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -111,15 +111,13 @@
 public:
     std::vector< sp<RenderNode> > cards;
     void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        android::uirenderer::Rect DUMMY;
-
         renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
         renderer->insertReorderBarrier(true);
 
         for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
             for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
                 sp<RenderNode> card = createCard(x, y, dp(100), dp(100));
-                renderer->drawRenderNode(card.get(), DUMMY, 0);
+                renderer->drawRenderNode(card.get());
                 cards.push_back(card);
             }
         }
@@ -153,13 +151,11 @@
 public:
     sp<RenderNode> card;
     void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        android::uirenderer::Rect DUMMY;
-
         renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
         renderer->insertReorderBarrier(true);
 
         card = createCard(40, 40, 200, 200);
-        renderer->drawRenderNode(card.get(), DUMMY, 0);
+        renderer->drawRenderNode(card.get());
 
         renderer->insertReorderBarrier(false);
     }
@@ -202,13 +198,11 @@
 public:
     sp<RenderNode> card;
     void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        android::uirenderer::Rect DUMMY;
-
         renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
         renderer->insertReorderBarrier(true);
 
         card = createCard(40, 40, 400, 400);
-        renderer->drawRenderNode(card.get(), DUMMY, 0);
+        renderer->drawRenderNode(card.get());
 
         renderer->insertReorderBarrier(false);
     }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d851ad7..eeac69a 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -38,6 +38,7 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.os.SystemClock;
 import android.os.ServiceManager;
 import android.provider.Settings;
@@ -64,6 +65,16 @@
     private static final AudioPortEventHandler sAudioPortEventHandler = new AudioPortEventHandler();
 
     /**
+     * System properties for whether the default microphone and speaker paths support
+     * near-ultrasound frequencies (range of 18 - 21 kHz).
+     */
+    private static final String SYSTEM_PROPERTY_MIC_NEAR_ULTRASOUND =
+            "persist.audio.mic.ultrasound";
+    private static final String SYSTEM_PROPERTY_SPEAKER_NEAR_ULTRASOUND =
+            "persist.audio.spkr.ultrasound";
+    private static final String DEFAULT_RESULT_FALSE_STRING = "false";
+
+    /**
      * Broadcast intent, a hint for applications that audio is about to become
      * 'noisy' due to a change in audio outputs. For example, this intent may
      * be sent when a wired headset is unplugged, or when an A2DP audio
@@ -3175,6 +3186,12 @@
         } else if (PROPERTY_OUTPUT_FRAMES_PER_BUFFER.equals(key)) {
             int outputFramesPerBuffer = AudioSystem.getPrimaryOutputFrameCount();
             return outputFramesPerBuffer > 0 ? Integer.toString(outputFramesPerBuffer) : null;
+        } else if (PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND.equals(key)) {
+            return SystemProperties.get(SYSTEM_PROPERTY_MIC_NEAR_ULTRASOUND,
+                    DEFAULT_RESULT_FALSE_STRING);
+        } else if (PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND.equals(key)) {
+            return SystemProperties.get(SYSTEM_PROPERTY_SPEAKER_NEAR_ULTRASOUND,
+                    DEFAULT_RESULT_FALSE_STRING);
         } else {
             // null or unknown key
             return null;
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index abb4257..a721923 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -51,5 +51,7 @@
         /** Called when internal ringer mode is evaluated, returns the new external ringer mode */
         int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller,
                 int ringerModeExternal, VolumePolicy policy);
+
+        boolean canVolumeDownEnterSilent();
     }
 }
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index a3442e3..95aaa7f 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -41,8 +41,9 @@
 public class ITvInputSessionWrapper extends ITvInputSession.Stub implements HandlerCaller.Callback {
     private static final String TAG = "TvInputSessionWrapper";
 
-    private static final int MESSAGE_HANDLING_DURATION_THRESHOLD_MILLIS = 50;
-    private static final int MESSAGE_TUNE_DURATION_THRESHOLD_MILLIS = 2000;
+    private static final int EXECUTE_MESSAGE_TIMEOUT_SHORT_MILLIS = 50;
+    private static final int EXECUTE_MESSAGE_TUNE_TIMEOUT_MILLIS = 2000;
+    private static final int EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS = 5 * 1000;
 
     private static final int DO_RELEASE = 1;
     private static final int DO_SET_MAIN = 2;
@@ -184,14 +185,18 @@
             }
         }
         long duration = System.currentTimeMillis() - startTime;
-        if (duration > MESSAGE_HANDLING_DURATION_THRESHOLD_MILLIS) {
+        if (duration > EXECUTE_MESSAGE_TIMEOUT_SHORT_MILLIS) {
             Log.w(TAG, "Handling message (" + msg.what + ") took too long time (duration="
                     + duration + "ms)");
-            if (msg.what == DO_TUNE && duration > MESSAGE_TUNE_DURATION_THRESHOLD_MILLIS) {
+            if (msg.what == DO_TUNE && duration > EXECUTE_MESSAGE_TUNE_TIMEOUT_MILLIS) {
                 throw new RuntimeException("Too much time to handle tune request. (" + duration
-                        + "ms > " + MESSAGE_TUNE_DURATION_THRESHOLD_MILLIS + "ms) "
+                        + "ms > " + EXECUTE_MESSAGE_TUNE_TIMEOUT_MILLIS + "ms) "
                         + "Consider handling the tune request in a separate thread.");
             }
+            if (duration > EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS) {
+                throw new RuntimeException("Too much time to handle a request. (type=" + msg.what +
+                        ", " + duration + "ms > " + EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS + "ms).");
+            }
         }
     }
 
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 601fa45..3272a23 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -1696,6 +1696,8 @@
          * @param rate The ratio between desired playback rate and normal one.
          * @param audioMode Audio playback mode. Must be one of the supported audio modes:
          * <ul>
+         * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_DEFAULT}
+         * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_STRETCH}
          * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE}
          * </ul>
          */
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 5156ae8..34c36c3 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -891,6 +891,8 @@
          * @param rate The ratio between desired playback rate and normal one.
          * @param audioMode Audio playback mode. Must be one of the supported audio modes:
          * <ul>
+         * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_DEFAULT}
+         * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_STRETCH}
          * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE}
          * </ul>
          * @see #onTimeShiftResume
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index d248b12..7e64b17 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -457,6 +457,8 @@
      * @param rate The ratio between desired playback rate and normal one.
      * @param audioMode Audio playback mode. Must be one of the supported audio modes:
      * <ul>
+     * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_DEFAULT}
+     * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_STRETCH}
      * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE}
      * </ul>
      */
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index 8c76665..294cd84 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -160,7 +160,7 @@
         // Writer. Do the detach unconditionally for opaque format now. see b/19977520
         if (mFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
             sp<Fence> fence;
-            ANativeWindowBuffer* buffer;
+            sp<GraphicBuffer> buffer;
             ALOGV("%s: One buffer is detached", __FUNCTION__);
             mProducer->detachNextBuffer(&buffer, &fence);
         }
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 8eba5c0..3f7571a 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Kopieer tans <xliff:g id="COUNT_0">%1$d</xliff:g> lêer.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Maak tans gereed vir kopieer …"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie kopieer nie</item>
+      <item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie kopieer nie</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Raak om besonderhede te bekyk"</string>
     <string name="retry" msgid="7564024179122207376">"Herprobeer"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Hierdie lêers is nie gekopieer nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index 61dc142..f4da9eb 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች በመቅዳት ላይ።</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"ቅጂ በማዘጋጀት ላይ…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መቅዳት አልተቻለም</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መቅዳት አልተቻለም</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"ዝርዝሮችን ለመመልከት ይንኩ።"</string>
     <string name="retry" msgid="7564024179122207376">"እንደገና ይሞክሩ"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"እነዚህ ፋይሎች አልተቀዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 35c200f..987e0a1 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -69,9 +69,15 @@
       <item quantity="one">جارٍ نسخ ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>).</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"جارٍ التحضير للنسخ ..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="zero">لم يتعذر نسخ أية ملفات (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+      <item quantity="two">تعذر نسخ ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+      <item quantity="few"> تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات</item>
+      <item quantity="many"> تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا</item>
+      <item quantity="other"> تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات</item>
+      <item quantity="one"> تعذر نسخ <xliff:g id="COUNT_0">%1$d</xliff:g> ملف</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"المس لعرض التفاصيل"</string>
     <string name="retry" msgid="7564024179122207376">"إعادة المحاولة"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"لم يتم نسخ هذه الملفات: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index d794e12..3f9774a 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Копира се <xliff:g id="COUNT_0">%1$d</xliff:g> файл.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Подготвя се за копиране…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла не можаха да се копират</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл не можа да се копира</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Докоснете, за да видите подробностите"</string>
     <string name="retry" msgid="7564024179122207376">"Нов опит"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Следните файлове не бяха копирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index f8ad27b..71ab447 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল অনুলিপি করা হচ্ছে৷</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"অনুলিপি করার জন্য প্রস্তুত করা হচ্ছে..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইলের প্রতিলিপি করা যায়নি</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইলের প্রতিলিপি করা যায়নি</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"বিশদ বিবরণ দেখতে স্পর্শ করুন"</string>
     <string name="retry" msgid="7564024179122207376">"পুনরায় চেষ্টা করুন"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"এই ফাইলগুলির প্রতিলিপি করা হয় নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index c2b4630..59cbd04 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">S\'està copiant <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"S\'està preparant una còpia…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">No s\'han pogut copiar <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
+      <item quantity="one">No s\'ha pogut copiar <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca per veure els detalls"</string>
     <string name="retry" msgid="7564024179122207376">"Torna-ho a provar"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Aquests fitxers no s\'han copiat: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index 9892fab..7697a99 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -67,9 +67,13 @@
       <item quantity="one">Kopírování <xliff:g id="COUNT_0">%1$d</xliff:g> souboru</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Příprava na kopírování…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="few">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> soubory</item>
+      <item quantity="many">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> souboru</item>
+      <item quantity="other">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
+      <item quantity="one">Nepodařilo se zkopírovat <xliff:g id="COUNT_0">%1$d</xliff:g> soubor</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Podrobnosti zobrazíte klepnutím"</string>
     <string name="retry" msgid="7564024179122207376">"Opakovat"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Tyto soubory nebyly zkopírovány: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index 5e110b3..919d785 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Tryk for at se yderligere oplysninger."</string>
     <string name="retry" msgid="7564024179122207376">"Prøv igen"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filer blev ikke kopieret: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index aa740e4..2fca9a9 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wird kopiert.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopieren wird vorbereitet…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht kopiert werden.</item>
+      <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht kopiert werden.</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Zum Einblenden von Details tippen"</string>
     <string name="retry" msgid="7564024179122207376">"Erneut versuchen"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Diese Dateien wurden nicht kopiert: <xliff:g id="LIST">%1$s</xliff:g>."</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index e5f40e8..409cca7 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Αντιγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
+      <item quantity="one">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Αγγίξτε για προβολή λεπτομερειών"</string>
     <string name="retry" msgid="7564024179122207376">"Επανάληψη"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Αυτά τα αρχεία δεν αντιγράφηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 2dc194a..4edbeda 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Copiando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">No se pudieron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
+      <item quantity="one">No se pudo copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca el elemento para ver más información."</string>
     <string name="retry" msgid="7564024179122207376">"Reintentar"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"No se copiaron estos archivos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index 70baa9f2..ac9692c 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Copiando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">No se han podido copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+      <item quantity="one">No se ha podido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca para ver más información"</string>
     <string name="retry" msgid="7564024179122207376">"Volver a intentar"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Archivos que no se han copiado: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index 95542cb..8f02871 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili kopeerimine.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopeerimise ettevalmistamine …"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud kopeerida</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud kopeerida</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Puudutage üksikasjade vaatamiseks"</string>
     <string name="retry" msgid="7564024179122207376">"Proovi uuesti"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Neid faile ei kopeeritud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index 7134674..3ddc0d1 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi kopiatzen.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopiatzeko prestatzen…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Ezin izan dira kopiatu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
+      <item quantity="one">Ezin izan da kopiatu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Xehetasunak ikusteko, ukitu hau."</string>
     <string name="retry" msgid="7564024179122207376">"Saiatu berriro"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ez dira kopiatu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index a5fabfe..a9fe251 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Kopioidaan <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Valmistellaan kopiointia…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Lue lisätietoja koskettamalla"</string>
     <string name="retry" msgid="7564024179122207376">"Yritä uudelleen"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Seuraavia tiedostoja ei kopioitu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index fce6615..b0c96e8 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other">Copier de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+      <item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Touchez ici pour afficher les détails"</string>
     <string name="retry" msgid="7564024179122207376">"Réessayer"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ces fichiers ne ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index dfbe1278..57fe11a 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other">Copie de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours…</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+      <item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Appuyez pour en savoir plus."</string>
     <string name="retry" msgid="7564024179122207376">"Réessayer"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Les fichiers suivants n\'ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index c9ca2bf..3b7cccf 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Copianto <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Non se puideron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Non se puido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Toca para ver detalles"</string>
     <string name="retry" msgid="7564024179122207376">"Tentar de novo"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Non se copiaron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index b1d60b2..19269b0 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें कॉपी की जा रही हैं.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"कॉपी करने की तैयारी हो रही है…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी नहीं बनाई जा सकती</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी नहीं बनाई जा सकती</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"विवरण देखने के लिए स्पर्श करें"</string>
     <string name="retry" msgid="7564024179122207376">"पुन: प्रयास करें"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"इन फ़ाइलों की कॉपी नहीं बनाई गई: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index cc0ce79..1357fc0 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -66,9 +66,12 @@
       <item quantity="other">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Priprema za kopiranje…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije kopirana</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu kopirane</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije kopirano</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Dodirnite da biste vidjeli pojedinosti"</string>
     <string name="retry" msgid="7564024179122207376">"Pokušaj ponovo"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ove datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index cf6c4fb..07c8ff1 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájl másolása.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Felkészülés a másolásra…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Érintse meg a részletek megtekintéséhez"</string>
     <string name="retry" msgid="7564024179122207376">"Újra"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"A következő fájlokat nem sikerült átmásolni: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index b612335..3a214a6 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի պատճենում:</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Պատճենման նախապատրաստում…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+      <item quantity="other">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Հպեք՝ մանրամասները դիտելու համար"</string>
     <string name="retry" msgid="7564024179122207376">"Կրկնել"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Հետևյալ ֆայլերը չեն պատճենվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index 99a8e2d..00818aa 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other">Afritar <xliff:g id="COUNT_1">%1$d</xliff:g> skrár.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Undirbúningur fyrir afritun…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
+      <item quantity="other">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Snertu til að skoða nánari upplýsingar"</string>
     <string name="retry" msgid="7564024179122207376">"Reyna aftur"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Þessar skrár voru ekki afritaðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index 7781dae..35afe54 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Copia di <xliff:g id="COUNT_0">%1$d</xliff:g> file in corso.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparazione alla copia…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Impossibile copiare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+      <item quantity="one">Impossibile copiare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Tocca per visualizzare i dettagli"</string>
     <string name="retry" msgid="7564024179122207376">"Riprova"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"I seguenti file non sono stati copiati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index 461ea26..dbf386b 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>個のファイルをコピーしています。</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"コピーの準備をしています…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ファイルをコピーできませんでした</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ファイルをコピーできませんでした</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"タップして詳細をご覧ください"</string>
     <string name="retry" msgid="7564024179122207376">"再試行"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"ファイル(<xliff:g id="LIST">%1$s</xliff:g>)をコピーできませんでした"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 6d13d9b..d2a6424 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды көшіру.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Көшіруге дайындау…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды көшіру мүмкін емес</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды көшіру мүмкін емес</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Толығырақ мәліметті көру үшін түртіңіз"</string>
     <string name="retry" msgid="7564024179122207376">"Қайталау"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Мына файлдар көшірілген жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index 2b2118a..a8cd4fe 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">កំពុងថតចម្លងឯកសារចំនួន <xliff:g id="COUNT_0">%1$d</xliff:g> ។</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"កំពុងរៀបចំចម្លង…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">មិនអាចចម្លងឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="one">មិនអាចចម្លងឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"ប៉ះ ដើម្បីមើលព័ត៌មានលម្អិត"</string>
     <string name="retry" msgid="7564024179122207376">"ព្យាយាមម្ដងទៀត"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"ឯកសារទាំងនេះមិនបានចម្លងទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index 19578e3..2cb4d8e 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"ನಕಲಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲು ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
+      <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲು ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"ವಿವರಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="retry" msgid="7564024179122207376">"ಮರುಪ್ರಯತ್ನಿಸು"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"ಈ ಫೈಲ್‌ಗಳನ್ನು ನಕಲು ಮಾಡಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index 003f9ec..3e6facf 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 복사합니다.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"사본 준비 중…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 복사할 수 없습니다.</item>
+      <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 복사할 수 없습니다.</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"세부정보를 보려면 터치하세요."</string>
     <string name="retry" msgid="7564024179122207376">"다시 시도"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"다음 파일이 복사되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index eba0df0..8f5bb25 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл көчүрүлүүдө.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Көчүрүүгө даярдалууда…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл көчүрүлбөй койду</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл көчүрүлбөй койду</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Чоо-жайын билүү үчүн тийип коюңуз"</string>
     <string name="retry" msgid="7564024179122207376">"Дагы аракет кылуу"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Төмөнкү файлдар көчүрүлгөн жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 45c4d66..f57071b 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">ກຳ​ລັງ​ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟ​ລ໌.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"ກຳ​ລັງ​ກຽມ​ອັດ​ສຳ​ເນົາ…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">ບໍ່​ສາ​ມາດ​ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟ​ລ໌​ໄດ້</item>
+      <item quantity="one">ບໍ່​ສາ​ມາດ​ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟ​ລ໌​ໄດ້</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"ສຳ​ພັດເພື່ອເບິ່ງລາຍລະອຽດ"</string>
     <string name="retry" msgid="7564024179122207376">"ລອງໃໝ່"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"ໄຟ​ລ໌​ເຫຼົ່າ​ນີ້​ບໍ່​ຖື​ກ​ອັດ​ສຳ​ເນົາ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index fec8ad7..66f5387 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -67,9 +67,13 @@
       <item quantity="other">Kopijuojama <xliff:g id="COUNT_1">%1$d</xliff:g> failų.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Ruošiamasi kopijuoti…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
+      <item quantity="few">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
+      <item quantity="many">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
+      <item quantity="other">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Palieskite, kad peržiūr. išsamią informaciją"</string>
     <string name="retry" msgid="7564024179122207376">"Bandyti dar kartą"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Šie failai nenukopijuoti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index d3d88b0..4e254a1 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -66,9 +66,12 @@
       <item quantity="other">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu kopēšana.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Gatavošanās kopēšanai…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="zero">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+      <item quantity="one">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
+      <item quantity="other">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Pieskarieties, lai skatītu informāciju"</string>
     <string name="retry" msgid="7564024179122207376">"Mēģināt vēlreiz"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Netika nokopēti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index 219d36f..cfe7947 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other">Се копираат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Се подготвува за копирање…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Не може да копира <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+      <item quantity="other">Не може да копираат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Допрете за да ги погледнете деталите"</string>
     <string name="retry" msgid="7564024179122207376">"Обидете се повторно"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Датотекиве не се ископирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index 7d1acf5..a5b5bbd 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ പകർത്തുന്നു.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"പകർപ്പിനായി തയ്യാറെടുക്കുന്നു…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ പകർത്താനായില്ല</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ പകർത്താനായില്ല</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"വിശദാംശങ്ങൾ കാണാൻ സ്‌പർശിക്കുക"</string>
     <string name="retry" msgid="7564024179122207376">"വീണ്ടും ശ്രമിക്കുക"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"ഈ ഫയലുകൾ പകർത്താനായില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index 71c245d..b7b1f23 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली कॉपी करीत आहे.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"कॉपी करण्‍यासाठी तयार करीत आहे…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल कॉपी करू शकलो नाही</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली कॉपी करू शकलो नाही</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"तपशील पाहण्यासाठी स्पर्श करा"</string>
     <string name="retry" msgid="7564024179122207376">"पुन्हा प्रयत्न करा"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"या फायली कॉपी झाल्या नाहीत: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index 0fa0f5c..9762c00 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Bersedia untuk salin..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
+      <item quantity="one">Tidak dapat menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Sentuh untuk melihat butiran"</string>
     <string name="retry" msgid="7564024179122207376">"Cuba semula"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Fail ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index c16295b..8f70690 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Kopierer <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering …"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Kunne ikke kopiere <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+      <item quantity="one">Kunne ikke kopiere <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Trykk for å se detaljer"</string>
     <string name="retry" msgid="7564024179122207376">"Prøv på nytt"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filene ble ikke kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index f041de3..283e6f2 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल प्रतिलिपि गर्दै।</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"प्रतिलिपिको लागि तयारी गर्दै ..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू प्रतिलिपि गर्न सकेन</item>
+      <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल प्रतिलिपि गर्न सकेन</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"विवरणहरू हेर्न छुनुहोस्"</string>
     <string name="retry" msgid="7564024179122207376">"पुनःप्रयास गर्नुहोस्"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"यी फाइलहरू प्रतिलिपि गरिएको थिएनः <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index a826710..ba37d81 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand kopiëren.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopiëren voorbereiden…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet kopiëren</item>
+      <item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet kopiëren</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Tik om details weer te geven"</string>
     <string name="retry" msgid="7564024179122207376">"Opnieuw proberen"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Deze bestanden zijn niet gekopieerd: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 884010f..79485ef 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -67,9 +67,13 @@
       <item quantity="one">Kopiowanie <xliff:g id="COUNT_0">%1$d</xliff:g> pliku.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Przygotowuję do kopiowania…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="few">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="many">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="other">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
+      <item quantity="one">Nie można skopiować <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Kliknij, by zobaczyć szczegóły"</string>
     <string name="retry" msgid="7564024179122207376">"Ponów"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Te pliki nie zostały skopiowane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 4d3222c..931b85c 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">A copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"A preparar para copiar…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
     <string name="retry" msgid="7564024179122207376">"Tentar novamente"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Os seguintes ficheiros não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index 067ba58..534caf0 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+      <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
     <string name="retry" msgid="7564024179122207376">"Repetir"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 786e538..7ffe10d 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -66,9 +66,12 @@
       <item quantity="one">Se copiază <xliff:g id="COUNT_0">%1$d</xliff:g> fișier.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Se pregătește copierea..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="few">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
+      <item quantity="other">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
+      <item quantity="one">Nu s-a putut copia <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Atingeți pentru a afișa detaliile"</string>
     <string name="retry" msgid="7564024179122207376">"Reîncercați"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Aceste fișiere nu au fost copiate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index 83dbb34..5c2e530 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -67,9 +67,13 @@
       <item quantity="other">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файла...</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Подготовка к копированию…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+      <item quantity="few">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+      <item quantity="many">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+      <item quantity="other">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Нажмите, чтобы узнать подробности."</string>
     <string name="retry" msgid="7564024179122207376">"Повторить"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Не удалось скопировать эти файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index de68d27..8692913 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -67,9 +67,13 @@
       <item quantity="one">Kopíruje sa <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Pripravuje sa na kopírovanie..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="few">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
+      <item quantity="many">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
+      <item quantity="other">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
+      <item quantity="one">Zlyhalo kopírovanie <xliff:g id="COUNT_0">%1$d</xliff:g> súboru</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Klepnutím zobrazíte podrobné informácie"</string>
     <string name="retry" msgid="7564024179122207376">"Skúsiť znova"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Tieto súbory neboli skopírované: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 7151950..9db6e13 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -66,9 +66,12 @@
       <item quantity="other">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Припрема се копирање…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку</item>
+      <item quantity="few">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке</item>
+      <item quantity="other">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Додирните да бисте видели детаље"</string>
     <string name="retry" msgid="7564024179122207376">"Покушај поново"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Следеће датотеке нису копиране: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 1716962..6e2eddf 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Kopierar <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopieringen förbereds …"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer gick inte att kopiera</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fil gick inte att kopiera</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Tryck här om du vill veta mer"</string>
     <string name="retry" msgid="7564024179122207376">"Försök igen"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Följande filer kopierades inte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index 3476331..5a3dd37 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Inanakili faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Inaanda kunakili..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Haikuweza kunakili faili <xliff:g id="COUNT_1">%1$d</xliff:g> </item>
+      <item quantity="one">Haikuweza kunakili faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Gusa ili uone maelezo"</string>
     <string name="retry" msgid="7564024179122207376">"Jaribu tena"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Faili hizi hazikunakiliwa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index f845de3..cc6b1df 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகலெடுக்கிறது.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"நகல் தயாராகிறது…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகலெடுக்க முடியவில்லை</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகலெடுக்க முடியவில்லை</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"விவரங்களைப் பார்க்க, தொடவும்"</string>
     <string name="retry" msgid="7564024179122207376">"மீண்டும் முயற்சிக்கவும்"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"நகலெடுக்கப்படாத கோப்புகள்: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index c9c83c8..cf13ec5 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను కాపీ చేస్తోంది.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"కాపీ చేయడానికి సిద్ధం చేస్తోంది…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను కాపీ చేయలేకపోయింది</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను కాపీ చేయలేకపోయింది</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"వివరాలను వీక్షించడానికి తాకండి"</string>
     <string name="retry" msgid="7564024179122207376">"మళ్లీ ప్రయత్నించు"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"ఈ ఫైల్‌లు కాపీ చేయబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index a596c1d..ac7bd5d 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">กำลังคัดลอก <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"กำลังเตรียมการคัดลอก…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">ไม่สามารถคัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+      <item quantity="one">ไม่สามารถคัดลอก <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"แตะเพื่อดูรายละเอียด"</string>
     <string name="retry" msgid="7564024179122207376">"ลองอีกครั้ง"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"ไม่มีการคัดลอกไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 891190c..bda4543 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya kopyalanıyor.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmak için hazırlanıyor…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya kopyalanamadı</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya kopyalanamadı</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Ayrıntıları görüntülemek için dokunun"</string>
     <string name="retry" msgid="7564024179122207376">"Yeniden dene"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Şu dosyalar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index fa0833d..999dc70 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -67,9 +67,13 @@
       <item quantity="other">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Підготовка до копіювання…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="one">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+      <item quantity="few">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файли</item>
+      <item quantity="many">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файлів</item>
+      <item quantity="other">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файлу</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Торкніться, щоб дізнатися більше"</string>
     <string name="retry" msgid="7564024179122207376">"Повторити"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ці файли не скопійовано: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 03f53fe..31c1909 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کاپی کی جا رہی ہے۔</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"کاپی کیلئے تیار ہو رہا ہے…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز کاپی نہیں کی جا سکیں</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کاپی نہیں کی جا سکی</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"تفصیلات دیکھنے کیلئے ٹچ کریں"</string>
     <string name="retry" msgid="7564024179122207376">"دوبارہ کوشش کریں"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"یہ فائلز کاپی نہیں کی گئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index 690d6d4..1b15b9f9 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Nuxsa olishga tayyorgarlik..."</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Batafsil ma’lumot olish uchun bosing"</string>
     <string name="retry" msgid="7564024179122207376">"Qayta urinish"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ushbu fayllardan nusxa olinmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index ecef48b..3bd7d78 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">Đang sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp.</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"Đang chuẩn bị sao chép…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">Không thể sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
+      <item quantity="one">Không thể sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"Chạm để xem chi tiết"</string>
     <string name="retry" msgid="7564024179122207376">"Thử lại"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"Những tệp này chưa được sao chép: <xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index 744ace1..96e3e3d 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">正在复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"正在准备复制…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">无法复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
+      <item quantity="one">无法复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"触摸可查看详情"</string>
     <string name="retry" msgid="7564024179122207376">"重试"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"以下文件无法复制:<xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 15d8316..1fa402e 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">正在複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
+      <item quantity="one">無法複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"輕觸即可查看詳情"</string>
     <string name="retry" msgid="7564024179122207376">"重試"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"以下檔案未能複製:<xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index 3a5e0ba..8de8402 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -65,9 +65,11 @@
       <item quantity="one">正在複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
     </plurals>
     <string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
-    <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+      <item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
+      <item quantity="one">無法複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="4483108577842961665">"輕觸即可查看詳細資料"</string>
     <string name="retry" msgid="7564024179122207376">"重試"</string>
-    <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="3715575000297709082">"未複製這些檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
index 1699809..25b1875 100644
--- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -120,7 +120,7 @@
             KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction(
                     true /* bypassHandler */);
             getContext().startActivityAsUser(INTENT_EMERGENCY_DIAL,
-                    new UserHandle(mLockPatternUtils.getCurrentUser()));
+                    new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
         }
     }
 
@@ -138,7 +138,7 @@
                     visible = mEnableEmergencyCallWhileSimLocked;
                 } else {
                     // Only show if there is a secure screen (pin/pattern/SIM pin/SIM puk);
-                    visible = mLockPatternUtils.isSecure();
+                    visible = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
                 }
             }
         }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 322be91..c4f4b9a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -63,7 +63,8 @@
         // start fresh
         resetPasswordText(false /* animate */);
         // if the user is currently locked out, enforce it.
-        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+        long deadline = mLockPatternUtils.getLockoutAttemptDeadline(
+                KeyguardUpdateMonitor.getCurrentUser());
         if (shouldLockout(deadline)) {
             handleAttemptLockout(deadline);
         } else {
@@ -106,7 +107,7 @@
 
     protected void verifyPasswordAndUnlock() {
         String entry = getPasswordText();
-        if (mLockPatternUtils.checkPassword(entry)) {
+        if (mLockPatternUtils.checkPassword(entry, KeyguardUpdateMonitor.getCurrentUser())) {
             mCallback.reportUnlockAttempt(true);
             mCallback.dismiss(true);
         } else {
@@ -116,7 +117,8 @@
                 mCallback.reportUnlockAttempt(false);
                 int attempts = KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
                 if (0 == (attempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
-                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+                            KeyguardUpdateMonitor.getCurrentUser());
                     handleAttemptLockout(deadline);
                 }
             }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index be71b034..2cf30ba 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -71,7 +71,7 @@
 
         @Override
         public void onTrustGrantedWithFlags(int flags, int userId) {
-            if (userId != mLockPatternUtils.getCurrentUser()) return;
+            if (userId != KeyguardUpdateMonitor.getCurrentUser()) return;
             if (!isAttachedToWindow()) return;
             boolean bouncerVisible = isVisibleToUser();
             boolean initiatedByUser =
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 9aa5729..557cd13 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -130,7 +130,8 @@
         mLockPatternView.setOnPatternListener(new UnlockPatternListener());
 
         // stealth mode will be the same for the life of this screen
-        mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
+        mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(
+                KeyguardUpdateMonitor.getCurrentUser()));
 
         // vibrate mode will be the same for the life of this screen
         mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
@@ -176,7 +177,8 @@
         mLockPatternView.clearPattern();
 
         // if the user is currently locked out, enforce it.
-        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+        long deadline = mLockPatternUtils.getLockoutAttemptDeadline(
+                KeyguardUpdateMonitor.getCurrentUser());
         if (deadline != 0) {
             handleAttemptLockout(deadline);
         } else {
@@ -213,7 +215,7 @@
         }
 
         public void onPatternDetected(List<LockPatternView.Cell> pattern) {
-            if (mLockPatternUtils.checkPattern(pattern)) {
+            if (mLockPatternUtils.checkPattern(pattern, KeyguardUpdateMonitor.getCurrentUser())) {
                 mCallback.reportUnlockAttempt(true);
                 mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
                 mCallback.dismiss(true);
@@ -230,7 +232,8 @@
                 int attempts = mKeyguardUpdateMonitor.getFailedUnlockAttempts();
                 if (registeredAttempt &&
                         0 == (attempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
-                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+                            KeyguardUpdateMonitor.getCurrentUser());
                     handleAttemptLockout(deadline);
                 } else {
                     mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 5af7783..ae4baad 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -261,7 +261,7 @@
 
         SecurityMode mode = mSecurityModel.getSecurityMode();
         final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
-        final int currentUser = mLockPatternUtils.getCurrentUser();
+        final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
         final DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
         final int failedAttemptsBeforeWipe =
                 dpm.getMaximumFailedPasswordsForWipe(null, currentUser);
@@ -296,7 +296,7 @@
                 (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
         }
         monitor.reportFailedUnlockAttempt();
-        mLockPatternUtils.reportFailedPasswordAttempt();
+        mLockPatternUtils.reportFailedPasswordAttempt(KeyguardUpdateMonitor.getCurrentUser());
         if (showTimeout) {
             showTimeoutDialog();
         }
@@ -321,7 +321,7 @@
     boolean showNextSecurityScreenOrFinish(boolean authenticated) {
         if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
         boolean finish = false;
-        if (mUpdateMonitor.getUserHasTrust(mLockPatternUtils.getCurrentUser())) {
+        if (mUpdateMonitor.getUserHasTrust(KeyguardUpdateMonitor.getCurrentUser())) {
             finish = true;
         } else if (SecurityMode.None == mCurrentSecuritySelection) {
             SecurityMode securityMode = mSecurityModel.getSecurityMode();
@@ -430,7 +430,8 @@
             KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
             if (success) {
                 monitor.clearFailedUnlockAttempts();
-                mLockPatternUtils.reportSuccessfulPasswordAttempt();
+                mLockPatternUtils.reportSuccessfulPasswordAttempt(
+                        KeyguardUpdateMonitor.getCurrentUser());
             } else {
                 KeyguardSecurityContainer.this.reportFailedUnlockAttempt();
             }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index 3eb31ad..454221a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -67,7 +67,8 @@
             return SecurityMode.SimPuk;
         }
 
-        final int security = mLockPatternUtils.getActivePasswordQuality();
+        final int security = mLockPatternUtils.getActivePasswordQuality(
+                KeyguardUpdateMonitor.getCurrentUser());
         switch (security) {
             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index af6360a..4e9621a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -200,9 +200,10 @@
     private String getOwnerInfo() {
         ContentResolver res = getContext().getContentResolver();
         String info = null;
-        final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
+        final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
+                KeyguardUpdateMonitor.getCurrentUser());
         if (ownerInfoEnabled) {
-            info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
+            info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
         }
         return info;
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1eec5325..b8d9053 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -244,6 +244,16 @@
     private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
     private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
 
+    private static int sCurrentUser;
+
+    public synchronized static void setCurrentUser(int currentUser) {
+        sCurrentUser = currentUser;
+    }
+
+    public synchronized static int getCurrentUser() {
+        return sCurrentUser;
+    }
+
     @Override
     public void onTrustChanged(boolean enabled, int userId, int flags) {
         mUserHasTrust.put(userId, enabled);
@@ -669,7 +679,7 @@
                 cb.onScreenTurnedOn();
             }
         }
-        startListeningForFingerprint();
+        updateFingerprintListeningState();
     }
 
     protected void handleScreenTurnedOff(int arg1) {
@@ -681,7 +691,7 @@
                 cb.onScreenTurnedOff(arg1);
             }
         }
-        stopListeningForFingerprint();
+        updateFingerprintListeningState();
     }
 
     /**
@@ -754,14 +764,14 @@
                             mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
                                     newUserId, 0, reply));
                             mSwitchingUser = true;
-                            stopListeningForFingerprint();
+                            updateFingerprintListeningState();
                         }
                         @Override
                         public void onUserSwitchComplete(int newUserId) throws RemoteException {
                             mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
                                     newUserId, 0));
                             mSwitchingUser = false;
-                            startListeningForFingerprint();
+                            updateFingerprintListeningState();
                         }
                         @Override
                         public void onForegroundProfileSwitch(int newProfileId) {
@@ -777,7 +787,20 @@
         trustManager.registerTrustListener(this);
 
         mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
-        startListeningForFingerprint();
+        updateFingerprintListeningState();
+    }
+
+    private void updateFingerprintListeningState() {
+        boolean shouldListenForFingerprint = shouldListenForFingerprint();
+        if (mFingerprintDetectionRunning && !shouldListenForFingerprint) {
+            stopListeningForFingerprint();
+        } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) {
+            startListeningForFingerprint();
+        }
+    }
+
+    private boolean shouldListenForFingerprint() {
+        return mScreenOn && mKeyguardIsVisible && !mSwitchingUser;
     }
 
     private void startListeningForFingerprint() {
@@ -794,7 +817,7 @@
         }
     }
 
-    public void stopListeningForFingerprint() {
+    private void stopListeningForFingerprint() {
         if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
         if (isFingerprintDetectionRunning()) {
             mFingerprintCancelSignal.cancel();
@@ -1052,6 +1075,7 @@
                 cb.onKeyguardVisibilityChangedRaw(isShowing);
             }
         }
+        updateFingerprintListeningState();
     }
 
     /**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 870f043..7bf2223 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2066,7 +2066,7 @@
                     LockPatternUtils lpu = new LockPatternUtils(mContext);
                     List<LockPatternView.Cell> cellPattern =
                             LockPatternUtils.stringToPattern(lockPattern);
-                    lpu.saveLockPattern(cellPattern, null);
+                    lpu.saveLockPattern(cellPattern, null, UserHandle.USER_OWNER);
                 } catch (IllegalArgumentException e) {
                     // Don't want corrupted lock pattern to hang the reboot process
                 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 7f826ef..d99f741 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -754,7 +754,7 @@
      */
     private byte[] getLockSettings() {
         final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
-        final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled();
+        final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled(UserHandle.myUserId());
         final String ownerInfo = lockPatternUtils.getOwnerInfo(UserHandle.myUserId());
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -871,7 +871,8 @@
                 }
                 switch (key) {
                     case KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED:
-                        lockPatternUtils.setOwnerInfoEnabled("1".equals(value));
+                        lockPatternUtils.setOwnerInfoEnabled("1".equals(value),
+                                UserHandle.myUserId());
                         break;
                     case KEY_LOCK_SETTINGS_OWNER_INFO:
                         lockPatternUtils.setOwnerInfo(value, UserHandle.myUserId());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 0d61606..1953e75 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1500,17 +1500,16 @@
         }
 
         public void onPackageRemovedLocked(String packageName, int userId) {
-            final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_OWNER);
-            SettingsState globalSettings = mSettingsStates.get(globalKey);
-            if (globalSettings != null) globalSettings.onPackageRemovedLocked(packageName);
-
-            final int secureKey = makeKey(SETTINGS_TYPE_SECURE, userId);
-            SettingsState secureSettings = mSettingsStates.get(secureKey);
-            if (secureSettings != null) secureSettings.onPackageRemovedLocked(packageName);
+            // Global and secure settings are signature protected. Apps signed
+            // by the platform certificate are generally not uninstalled  and
+            // the main exception is tests. We trust components signed
+            // by the platform certificate and do not do a clean up after them.
 
             final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
             SettingsState systemSettings = mSettingsStates.get(systemKey);
-            if (systemSettings != null) systemSettings.onPackageRemovedLocked(packageName);
+            if (systemSettings != null) {
+                systemSettings.onPackageRemovedLocked(packageName);
+            }
         }
 
         private SettingsState peekSettingsStateLocked(int key) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 8d99a64..f853f3f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -153,7 +153,7 @@
         final int settingCount = mSettings.size();
         for (int i = settingCount - 1; i >= 0; i--) {
             String name = mSettings.keyAt(i);
-            // Settings defined by use are never dropped.
+            // Settings defined by us are never dropped.
             if (Settings.System.PUBLIC_SETTINGS.contains(name)
                     || Settings.System.PRIVATE_SETTINGS.contains(name)) {
                 continue;
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_fingerprint_ridges_animation.xml
new file mode 100644
index 0000000..c6a4622
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_fingerprint_ridges_animation.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="566"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+        <objectAnimator
+            android:duration="1066"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="800"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-720.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_1_animation.xml
new file mode 100644
index 0000000..0e2c2f0
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_1_animation.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="183"
+            android:propertyName="rotation"
+            android:valueFrom="285.0"
+            android:valueTo="285.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="516"
+            android:propertyName="rotation"
+            android:valueFrom="285.0"
+            android:valueTo="90.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_2_animation.xml
new file mode 100644
index 0000000..c01010d
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_2_animation.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="283"
+            android:propertyName="scaleX"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="scaleX"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="283"
+            android:propertyName="scaleY"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="scaleY"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="283"
+            android:propertyName="rotation"
+            android:valueFrom="184.0"
+            android:valueTo="184.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="316"
+            android:propertyName="rotation"
+            android:valueFrom="184.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_path_3_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_path_3_animation.xml
new file mode 100644
index 0000000..454be24
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_path_3_animation.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="233"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="466"
+            android:propertyName="trimPathStart"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation.xml
new file mode 100644
index 0000000..faeecf4
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="133"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_animation.xml
new file mode 100644
index 0000000..3bacf03
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_animation.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="66"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation.xml
new file mode 100644
index 0000000..80a0faa
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="116"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+    </set>
+    <objectAnimator
+        android:duration="166"
+        android:propertyName="trimPathStart"
+        android:valueFrom="1.0"
+        android:valueTo="0.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_animation.xml
new file mode 100644
index 0000000..3a18296
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_animation.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="1.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation.xml
new file mode 100644
index 0000000..1e16df7
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="166"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="166"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_animation.xml
new file mode 100644
index 0000000..a1cf8df
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="150"
+        android:propertyName="trimPathStart"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation.xml
new file mode 100644
index 0000000..f88c070
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="250"
+        android:propertyName="trimPathEnd"
+        android:valueFrom="0.0"
+        android:valueTo="1.0"
+        android:valueType="floatType"
+        android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_animation.xml
new file mode 100644
index 0000000..ada7c10
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_animation.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation.xml
new file mode 100644
index 0000000..e6b12da
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="16"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="216"
+            android:propertyName="trimPathEnd"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="133"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="266"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_animation.xml
new file mode 100644
index 0000000..8c6e71d
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_animation.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="33"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="150"
+            android:propertyName="trimPathStart"
+            android:valueFrom="0.0"
+            android:valueTo="1.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_animation.xml
new file mode 100644
index 0000000..c6a4622
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_animation.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="100"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="0.0"
+            android:valueType="floatType"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="566"
+            android:propertyName="rotation"
+            android:valueFrom="0.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+        <objectAnimator
+            android:duration="1066"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-305.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+        <objectAnimator
+            android:duration="800"
+            android:propertyName="rotation"
+            android:valueFrom="-305.0"
+            android:valueTo="-720.0"
+            android:valueType="floatType"
+            android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state.xml
new file mode 100644
index 0000000..cc8aba9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="lockscreen_fingerprint_error_state"
+    android:width="32dp"
+    android:viewportWidth="32"
+    android:height="32dp"
+    android:viewportHeight="32" >
+    <group
+        android:name="white_fingerprint_ridges"
+        android:translateX="16.125"
+        android:translateY="19.75" >
+        <group
+            android:name="white_fingerprint_ridges_pivot"
+            android:translateX="33.2085"
+            android:translateY="30.91685" >
+            <group
+                android:name="ridge_5" >
+                <path
+                    android:name="ridge_5_path"
+                    android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0.5"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round" />
+            </group>
+            <group
+                android:name="ridge_4" >
+                <path
+                    android:name="ridge_7_path"
+                    android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0.5"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round" />
+            </group>
+            <group
+                android:name="ridge_3" >
+                <path
+                    android:name="ridge_6_path"
+                    android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0.5"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round" />
+            </group>
+            <group
+                android:name="ridge_2" >
+                <path
+                    android:name="ridge_2_path"
+                    android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0.5"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round" />
+            </group>
+            <group
+                android:name="ridge_1"
+                android:translateX="-97.5"
+                android:translateY="-142.5" >
+                <path
+                    android:name="ridge_1_path"
+                    android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0.5"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="fingerprint_ridges"
+        android:translateX="16.125"
+        android:translateY="19.75" >
+        <group
+            android:name="fingerprint_ridges_pivot"
+            android:translateX="33.2085"
+            android:translateY="30.91685" >
+            <group
+                android:name="ridge_6" >
+                <path
+                    android:name="ridge_5_path_0"
+                    android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
+                    android:strokeColor="#FFF2501D"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round"
+                    android:trimPathEnd="0" />
+            </group>
+            <group
+                android:name="ridge_7" >
+                <path
+                    android:name="ridge_7_path_0"
+                    android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
+                    android:strokeColor="#FFF2501D"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round"
+                    android:trimPathEnd="0" />
+            </group>
+            <group
+                android:name="ridge_8" >
+                <path
+                    android:name="ridge_6_path_0"
+                    android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
+                    android:strokeColor="#FFF2501D"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round"
+                    android:trimPathEnd="0" />
+            </group>
+            <group
+                android:name="ridge_9" >
+                <path
+                    android:name="ridge_2_path_0"
+                    android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
+                    android:strokeColor="#FFF2501D"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round"
+                    android:trimPathStart="1" />
+            </group>
+            <group
+                android:name="ridge_10"
+                android:translateX="-97.5"
+                android:translateY="-142.5" >
+                <path
+                    android:name="ridge_1_path_0"
+                    android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
+                    android:strokeColor="#FFF2501D"
+                    android:strokeWidth="1.45"
+                    android:strokeLineCap="round"
+                    android:trimPathEnd="0" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="exclamation"
+        android:translateX="16"
+        android:translateY="16" >
+        <group
+            android:name="group_2"
+            android:scaleX="0"
+            android:scaleY="0"
+            android:rotation="184" >
+            <path
+                android:name="path_2_merged"
+                android:pathData="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
+                android:fillColor="#FFF2501D" />
+        </group>
+    </group>
+    <group
+        android:name="circle_outline"
+        android:translateX="16"
+        android:translateY="16" >
+        <group
+            android:name="group_1"
+            android:scaleX="1.12734"
+            android:scaleY="1.12734"
+            android:rotation="285" >
+            <path
+                android:name="path_3"
+                android:pathData="M 0.0101470947266,10.8087768555 c -5.96701049805,0.0 -10.8000183105,-4.8330078125 -10.8000183105,-10.8000488281 c 0.0,-5.96691894531 4.8330078125,-10.7999267578 10.8000183105,-10.7999267578 c 5.96697998047,0.0 10.799987793,4.8330078125 10.799987793,10.7999267578 c 0.0,5.96704101562 -4.8330078125,10.8000488281 -10.799987793,10.8000488281 Z"
+                android:strokeColor="#FFF2501D"
+                android:strokeWidth="2"
+                android:trimPathStart="1" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_animation.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_animation.xml
new file mode 100644
index 0000000..8cc8ac2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_animation.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/lockscreen_fingerprint_error_state" >
+    <target
+        android:name="white_fingerprint_ridges"
+        android:animation="@anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_animation" />
+    <target
+        android:name="ridge_5_path"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_5_path_animation" />
+    <target
+        android:name="ridge_7_path"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_7_path_animation" />
+    <target
+        android:name="ridge_6_path"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_6_path_animation" />
+    <target
+        android:name="ridge_2_path"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_2_path_animation" />
+    <target
+        android:name="ridge_1_path"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_1_path_animation" />
+    <target
+        android:name="fingerprint_ridges"
+        android:animation="@anim/lockscreen_fingerprint_error_state_fingerprint_ridges_animation" />
+    <target
+        android:name="ridge_5_path_0"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation" />
+    <target
+        android:name="ridge_7_path_0"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation" />
+    <target
+        android:name="ridge_6_path_0"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation" />
+    <target
+        android:name="ridge_2_path_0"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation" />
+    <target
+        android:name="ridge_1_path_0"
+        android:animation="@anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation" />
+    <target
+        android:name="group_2"
+        android:animation="@anim/lockscreen_fingerprint_error_state_group_2_animation" />
+    <target
+        android:name="group_1"
+        android:animation="@anim/lockscreen_fingerprint_error_state_group_1_animation" />
+    <target
+        android:name="path_3"
+        android:animation="@anim/lockscreen_fingerprint_error_state_path_3_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0.xml
new file mode 100644
index 0000000..39c5211
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1.xml
new file mode 100644
index 0000000..d3ae9d7
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2.xml
new file mode 100644
index 0000000..e10db01
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.8,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3.xml
new file mode 100644
index 0000000..736eac6
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2015 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<pathInterpolator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index fca8231..1057464 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -61,7 +61,7 @@
         android:scaleType="center"
         android:contentDescription="@string/accessibility_phone_button" />
 
-    <com.android.systemui.statusbar.KeyguardAffordanceView
+    <com.android.systemui.statusbar.phone.LockIcon
         android:id="@+id/lock_icon"
         android:layout_width="@dimen/keyguard_affordance_width"
         android:layout_height="@dimen/keyguard_affordance_height"
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 2eb99ba..ddff0f0 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -18,7 +18,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:background="@drawable/qs_detail_background"
-        android:paddingBottom="16dp"
+        android:paddingBottom="8dp"
         android:orientation="vertical">
 
     <FrameLayout
@@ -30,7 +30,7 @@
     <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:paddingEnd="16dp"
+            android:paddingEnd="8dp"
             android:gravity="end">
 
         <TextView
diff --git a/packages/SystemUI/res/layout/segmented_button.xml b/packages/SystemUI/res/layout/segmented_button.xml
index ead735f..b7a7932 100644
--- a/packages/SystemUI/res/layout/segmented_button.xml
+++ b/packages/SystemUI/res/layout/segmented_button.xml
@@ -19,10 +19,10 @@
     android:layout_height="wrap_content"
     android:layout_marginStart="@dimen/segmented_button_spacing"
     android:layout_weight="1"
-    android:paddingStart="8dp"
-    android:gravity="start|center_vertical"
+    android:gravity="center"
     android:maxLines="2"
+    android:lineSpacingMultiplier="1.05026"
     android:textColor="@color/segmented_button_text_selector"
     android:background="@drawable/btn_borderless_rect"
-    android:textAppearance="@style/TextAppearance.Volume.ZenSwitchSummary"
-    android:minHeight="48dp" />
+    android:textAppearance="@style/TextAppearance.QS.SegmentedButton"
+    android:minHeight="64dp" />
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index c86e9dc..0ed1e2a 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -21,40 +21,31 @@
     android:layout_marginBottom="4dp"
     android:layout_marginLeft="@dimen/notification_side_padding"
     android:layout_marginRight="@dimen/notification_side_padding"
-    android:layout_marginTop="4dp"
     android:background="@drawable/volume_dialog_background"
     android:translationZ="4dp" >
 
     <com.android.keyguard.AlphaOptimizedImageButton
         android:id="@+id/volume_expand_button"
         style="@style/VolumeButtons"
-        android:layout_alignParentLeft="true"
         android:layout_width="@dimen/volume_button_size"
         android:layout_height="@dimen/volume_button_size"
+        android:layout_alignParentLeft="true"
         android:clickable="true"
         android:soundEffectsEnabled="false"
-        android:src="@drawable/ic_volume_collapse_animation" />
+        android:src="@drawable/ic_volume_collapse_animation"
+        tools:ignore="RtlHardcoded" />
 
     <LinearLayout
         android:id="@+id/volume_dialog_content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
-        android:paddingBottom="4dp"
-        android:paddingTop="6dp" >
+        android:paddingBottom="8dp"
+        android:paddingTop="8dp" >
 
         <!-- volume rows added and removed here! :-) -->
 
-        <FrameLayout
-            android:id="@+id/volume_footer"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            tools:ignore="UselessParent" >
-
-            <include layout="@layout/volume_text_footer" />
-
-            <include layout="@layout/volume_zen_footer" />
-        </FrameLayout>
+        <include layout="@layout/volume_zen_footer" />
     </LinearLayout>
 
 </RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index b51aa96..53ae61b 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -16,16 +16,15 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingStart="4dp"
-    android:paddingEnd="4dp"
-    android:clipChildren="false" >
+    android:clipChildren="false"
+    android:paddingEnd="8dp"
+    android:paddingStart="8dp" >
 
     <TextView
         android:id="@+id/volume_row_header"
         style="?android:attr/textAppearanceButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:alpha="@dimen/volume_secondary_alpha"
         android:ellipsize="end"
         android:maxLines="1"
         android:paddingBottom="0dp"
@@ -50,8 +49,8 @@
         android:layout_below="@id/volume_row_header"
         android:layout_toEndOf="@id/volume_row_icon"
         android:layout_toStartOf="@+id/volume_settings_button"
-        android:paddingEnd="4dp"
-        android:paddingStart="4dp"
+        android:paddingEnd="8dp"
+        android:paddingStart="8dp"
         android:progressTint="@android:color/white"
         android:thumbTint="@android:color/white" />
 
diff --git a/packages/SystemUI/res/layout/volume_text_footer.xml b/packages/SystemUI/res/layout/volume_text_footer.xml
deleted file mode 100644
index 7436488..0000000
--- a/packages/SystemUI/res/layout/volume_text_footer.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/volume_text_footer"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:visibility="gone"
-    tools:ignore="UselessParent" >
-
-    <TextView
-        android:id="@+id/volume_footline_text"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBaseline="@+id/volume_footline_action_button"
-        android:alpha="@dimen/volume_secondary_alpha"
-        android:fontFamily="sans-serif"
-        android:paddingEnd="8dp"
-        android:paddingStart="13dp"
-        android:textColor="?android:attr/textColorPrimary" />
-
-    <Button
-        android:id="@+id/volume_footline_action_button"
-        style="@android:style/Widget.Material.Button.Borderless"
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/volume_button_size"
-        android:layout_toEndOf="@id/volume_footline_text"
-        android:layout_toStartOf="@+id/volume_settings_button"
-        android:alpha="@dimen/volume_secondary_alpha"
-        android:paddingEnd="0dp"
-        android:paddingStart="0dp" />
-
-    <com.android.keyguard.AlphaOptimizedImageButton
-        android:id="@+id/volume_settings_button"
-        style="@style/VolumeButtons"
-        android:layout_width="@dimen/volume_button_size"
-        android:layout_height="@dimen/volume_button_size"
-        android:layout_alignParentEnd="true"
-        android:src="@drawable/ic_volume_settings" />
-
-</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_zen_footer.xml b/packages/SystemUI/res/layout/volume_zen_footer.xml
index dcdc859..9e761e2 100644
--- a/packages/SystemUI/res/layout/volume_zen_footer.xml
+++ b/packages/SystemUI/res/layout/volume_zen_footer.xml
@@ -20,93 +20,58 @@
     android:layout_height="wrap_content"
     android:orientation="vertical" > <!-- extends LinearLayout -->
 
-    <LinearLayout
-        android:id="@+id/volume_zen_switch_bar"
+    <View
+        android:id="@+id/zen_embedded_divider"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/volume_button_size"
-        android:layout_marginStart="4dp"
-        android:layout_marginEnd="4dp"
-        android:clickable="true"
-        android:orientation="horizontal" >
+        android:layout_height="1dp"
+        android:layout_marginBottom="8dp"
+        android:layout_marginTop="8dp"
+        android:background="#4dffffff" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:paddingEnd="8dp"
+        android:paddingStart="8dp" >
 
         <ImageView
-            android:id="@+id/volume_zen_switch_bar_icon"
+            android:id="@+id/volume_zen_icon"
             android:layout_width="@dimen/volume_button_size"
             android:layout_height="@dimen/volume_button_size"
+            android:layout_marginEnd="7dp"
             android:scaleType="center"
             android:src="@drawable/ic_dnd" />
 
-        <TextView
+        <LinearLayout
             android:layout_width="0dp"
-            android:layout_height="fill_parent"
+            android:layout_height="wrap_content"
             android:layout_weight="1"
-            android:gravity="center_vertical"
-            android:textDirection="locale"
-            android:padding="3dp"
-            android:text="@string/volume_zen_switch_text"
-            android:textAppearance="@style/TextAppearance.Volume.ZenSwitch" />
+            android:orientation="vertical" >
 
-        <Switch
-            android:id="@+id/volume_zen_switch"
-            android:layout_width="wrap_content"
-            android:layout_height="fill_parent"
-            android:layout_marginEnd="11dp" />
+            <TextView
+                android:id="@+id/volume_zen_summary_line_1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.Volume.ZenSummary" />
 
-    </LinearLayout>
-
-    <RelativeLayout
-        android:id="@+id/volume_zen_panel_summary"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/volume_button_size"
-        android:layout_marginStart="@dimen/volume_button_size"
-        android:paddingEnd="7dp"
-        android:paddingStart="7dp" >
+            <TextView
+                android:id="@+id/volume_zen_summary_line_2"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.Volume.ZenDetail" />
+        </LinearLayout>
 
         <TextView
-            android:id="@+id/volume_zen_panel_summary_line_1"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:textAppearance="@style/TextAppearance.Volume.ZenSwitchSummary" />
-
-        <TextView
-            android:id="@+id/volume_zen_panel_summary_line_2"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/volume_zen_panel_summary_line_1"
-            android:textAppearance="@style/TextAppearance.Volume.ZenSwitchDetail" />
-    </RelativeLayout>
-
-    <include layout="@layout/zen_mode_panel" />
-
-    <LinearLayout
-        android:id="@+id/volume_zen_mode_panel_buttons"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="4dp"
-        android:layout_marginEnd="4dp"
-        android:gravity="end" >
-
-        <TextView
-            android:id="@+id/volume_zen_mode_panel_more"
-            style="@style/QSBorderlessButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="8dp"
-            android:clickable="true"
-            android:focusable="true"
-            android:minWidth="132dp"
-            android:text="@string/quick_settings_more_settings"
-            android:textAppearance="@style/TextAppearance.QS.DetailButton" />
-
-        <TextView
-            android:id="@+id/volume_zen_mode_panel_done"
+            android:id="@+id/volume_zen_end_now"
             style="@style/QSBorderlessButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:clickable="true"
             android:focusable="true"
-            android:minWidth="66dp"
-            android:text="@string/quick_settings_done"
+            android:minWidth="91dp"
+            android:text="@string/volume_zen_end_now"
             android:textAppearance="@style/TextAppearance.QS.DetailButton" />
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index b676bce..595c9ed 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -22,81 +22,21 @@
     android:clipChildren="false"
     android:orientation="vertical" >
 
-    <FrameLayout
-        android:id="@+id/zen_buttons_container"
+    <com.android.systemui.volume.SegmentedButtons
+        android:id="@+id/zen_buttons"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:minHeight="8dp"
-        android:layout_marginStart="39dp"
-        android:elevation="4dp"
-        android:background="@drawable/qs_background_secondary" >
-
-        <com.android.systemui.volume.SegmentedButtons
-            android:id="@+id/zen_buttons"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="8dp"
-            android:layout_marginRight="8dp"
-            android:layout_marginBottom="8dp"
-            android:clipChildren="false" />
-    </FrameLayout>
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="8dp" />
 
     <View
         android:id="@+id/zen_embedded_divider"
         android:layout_width="match_parent"
+        android:layout_marginTop="8dp"
         android:layout_height="1dp"
-        android:visibility="gone"
         android:background="#4dffffff" />
 
     <RelativeLayout
-        android:id="@+id/zen_subhead"
-        android:layout_width="match_parent"
-        android:layout_height="62dp"
-        android:layout_marginStart="39dp"
-        android:gravity="center_vertical"
-        android:paddingLeft="8dp"
-        android:paddingRight="8dp" >
-
-        <TextView
-            android:id="@+id/zen_subhead_collapsed"
-            android:layout_width="wrap_content"
-            android:layout_height="48dp"
-            android:layout_gravity="center_vertical"
-            android:gravity="center_vertical"
-            android:paddingLeft="8dp"
-            android:paddingRight="4dp"
-            android:background="@drawable/btn_borderless_rect"
-            android:clickable="true"
-            android:drawableEnd="@drawable/qs_subhead_caret"
-            android:maxLines="2"
-            android:ellipsize="end"
-            android:textAppearance="@style/TextAppearance.QS.Subhead" />
-
-        <TextView
-            android:id="@+id/zen_subhead_expanded"
-            android:layout_width="wrap_content"
-            android:layout_height="48dp"
-            android:layout_gravity="center_vertical"
-            android:gravity="center_vertical"
-            android:paddingLeft="8dp"
-            android:maxLines="2"
-            android:ellipsize="end"
-            android:textAppearance="@style/TextAppearance.QS.Subhead" />
-
-        <ImageView
-            android:id="@+id/zen_more_settings"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:layout_alignParentEnd="true"
-            android:background="@drawable/btn_borderless_rect"
-            android:clickable="true"
-            android:contentDescription="@string/accessibility_desc_settings"
-            android:scaleType="center"
-            android:src="@drawable/ic_settings" />
-
-    </RelativeLayout>
-
-    <RelativeLayout
         android:id="@+id/zen_introduction"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
@@ -122,10 +62,9 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="12dp"
-            android:layout_marginStart="55dp"
+            android:layout_marginStart="24dp"
             android:lineSpacingMultiplier="1.20029"
             android:layout_toStartOf="@id/zen_introduction_confirm"
-            android:text="@string/zen_priority_introduction"
             android:textAppearance="@style/TextAppearance.QS.Introduction" />
 
         <TextView
@@ -141,6 +80,12 @@
             android:text="@string/zen_priority_customize_button"
             android:textAppearance="@style/TextAppearance.QS.DetailButton.White" />
 
+        <View
+            android:layout_width="0dp"
+            android:layout_height="16dp"
+            android:layout_below="@id/zen_introduction_message"
+            android:layout_alignParentEnd="true" />
+
     </RelativeLayout>
 
     <LinearLayout
@@ -149,7 +94,7 @@
         android:layout_height="wrap_content"
         android:layout_marginTop="8dp"
         android:layout_marginEnd="4dp"
-        android:layout_marginStart="39dp"
+        android:layout_marginStart="4dp"
         android:orientation="vertical"
         android:paddingBottom="@dimen/zen_mode_condition_detail_bottom_padding" />
 
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 2226a07..51a5a19 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -365,7 +365,7 @@
     <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Din enhed administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nDin administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er knyttet til din enhed, og din enheds placeringsoplysninger. Kontakt din administrator, hvis du vil have flere oplysninger."</string>
     <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Din arbejdsprofil administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nDin administrator kan overvåge din netværksaktivitet, herunder e-mails, apps og sikre websites.\n\nKontakt din administrator, hvis du vil have flere oplysninger."</string>
     <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Din enhed administreres af:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nDin arbejdsprofil administreres af:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nDin administrator kan overvåge din enhed og netværksaktivitet, herunder e-mails, apps og sikre websites.\n\nKontakt din administrator, hvis du vil have flere oplysninger."</string>
-    <string name="monitoring_description_vpn" msgid="912328761766161919">"Du har givet en app tilladelse til at oprette en VPN-forbindelse.\n\nDenne app kan overvåge din netværksaktivitet, herunder e-mails, apps og sikre websites."</string>
+    <string name="monitoring_description_vpn" msgid="912328761766161919">"Du har givet en app tilladelse til at oprette en VPN-forbindelse.\n\nDenne app kan overvåge din enhed og netværksaktivitet, herunder e-mails, apps og sikre websites."</string>
     <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Din enhed administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nDin administrator kan overvåge og administrere indstillinger, virksomhedsadgang, apps, data, der er knyttet til din enhed, og din enheds placeringsoplysninger.\n\nDu har forbindelse til et VPN, som kan overvåge din netværksaktivitet, herunder e-mails, apps og websites.\n\nKontakt din administrator, hvis du vil have flere oplysninger."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Din arbejdsprofil administreres af <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nDin administrator kan overvåge din netværksaktivitet, herunder e-mails, apps og sikre websites.\n\nKontakt din administrator, hvis du vil have flere oplysninger.\n\nDu har også forbindelse til et VPN, som kan overvåge din netværksaktivitet."</string>
     <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Din enhed administreres af <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nDin arbejdsprofil administreres af:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nDin administrator kan overvåge din netværksaktivitet, herunder e-mail, apps og sikre websites.\n\nKontakt din administrator, hvis du vil have flere oplysninger.\n\nDu har også forbindelse til et VPN, som kan overvåge din personlige netværksaktivitet."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 2822445..70890b3 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -230,7 +230,7 @@
     <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Ruutu on nyt lukittu vaakasuuntaan."</string>
     <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Ruutu on nyt lukittu pystysuuntaan."</string>
     <string name="dessert_case" msgid="1295161776223959221">"Jälkiruokavitriini"</string>
-    <string name="start_dreams" msgid="7219575858348719790">"Unelmat"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Lepotila"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Älä häiritse"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Vain tärkeät"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 1d2b12b..3e3a91d 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -368,7 +368,7 @@
     <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVotre administrateur peut contrôler votre activité sur le réseau (courriels, applications et sites sécurisés).\n\nPour en savoir plus, communiquez avec votre administrateur."</string>
     <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Votre appareil est géré par \n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nVotre profil professionnel est géré par \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nVotre administrateur peut contrôler l\'activité de votre appareil et votre activité réseau (courriels, applications et sites sécurisés).\n\nPour en savoir plus, communiquez avec votre administrateur."</string>
     <string name="monitoring_description_vpn" msgid="912328761766161919">"Vous avez autorisé une application à configurer une connexion RPV.\n\nCette application peut contrôler l\'activité de votre appareil et votre activité sur le réseau (courriels, applications et sites sécurisés)."</string>
-    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Votre appareil géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVotre administrateur peut contrôler et gérer les paramètres, l\'accès aux contenus de l\'entreprise, les applications, les données associées à cet appareil et les données de localisation de celui-ci.\n\nVous êtes connecté à un RPV qui peut contrôler votre activité sur le réseau (courriels, applications et sites Web).\n\nPour en savoir plus, communiquez avec votre administrateur."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Votre appareil est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVotre administrateur peut contrôler et gérer les paramètres, l\'accès aux contenus de l\'entreprise, les applications, les données associées à cet appareil et les données de localisation de celui-ci.\n\nVous êtes connecté à un RPV qui peut contrôler votre activité sur le réseau (courriels, applications et sites Web).\n\nPour en savoir plus, communiquez avec votre administrateur."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Votre profil professionnel est géré par <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVotre administrateur peut contrôler votre activité sur le réseau (courriels, applications et sites sécurisés).\n\nPour en savoir plus, communiquez avec votre administrateur.\n\nVous êtes également connecté à un RPV qui peut contrôler votre activité sur le réseau."</string>
     <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Votre appareil est géré par <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nVotre profil professionnel est géré par \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nVotre administrateur peut contrôler votre activité sur le réseau (courriels, applications et sites sécurisés).\n\nPour en savoir plus, communiquez avec votre administrateur.\n\nVous êtes également connecté à un RPV qui peut contrôler votre activité personnelle sur le réseau."</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"L\'appareil restera verrouillé jusqu\'à ce que vous le déverrouilliez manuellement"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 9acc498..3fd5003 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -364,7 +364,7 @@
     <string name="disconnect_vpn" msgid="1324915059568548655">"Անջատել VPN-ը"</string>
     <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Սարքի կառավարիչն է՝ <xliff:g id="ORGANIZATION">%1$s</xliff:g>:\n\nԱդմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ հաշիվը, հավելվածները, սարքի հետ առնչվող և սարքի տեղադրության տվյալները: Լրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:"</string>
     <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Աշխատանքային պրոֆիլի կառավարիչն է՝ <xliff:g id="ORGANIZATION">%1$s</xliff:g>:\n\nԱդմինիստրատորը կարող է վերահսկել ցանցում ունեցած գործունեությունը, այդ թվում՝ էլեկտրոնային նամակները, հավելվածները և վստահելի կայքերը:\n\nԼրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:"</string>
-    <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Սարքի կառավարիչ՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>:\nՊրոֆիլի կառավարիչ՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>:\n\nԱդմինիստրատորը կարող է վերահսկել ձեր սարքի և ցանցի գործունեությունը՝ նամակները, հավելվածները և վստահելի կայքերը:\n\nԼրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:"</string>
+    <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Սարքի կառավարիչ՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>:\nԱշխատանքային պրոֆիլի կառավարիչ՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>:\n\nԱդմինիստրատորը կարող է վերահսկել ձեր սարքի և ցանցի գործունեությունը՝ նամակները, հավելվածները և վստահելի կայքերը:\n\nԼրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:"</string>
     <string name="monitoring_description_vpn" msgid="912328761766161919">"Ինչ-որ հավելվածի թույլ եք տվեք հաստատել VPN կապակցում:\n\nԱյդ հավելվածը կարող է վերահսկել ձեր սարքի և ցանցի գործունեությունը, այդ թվում նաև՝ էլեկտրոնային նամակները, հավելվածները և վստահելի կայքերը:"</string>
     <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Սարքի կառավարիչն է՝ <xliff:g id="ORGANIZATION">%1$s</xliff:g>:\n\nԱդմինիստրատորը կարող է վերահսկել և կառավարել կարգավորումները, կորպորատիվ հաշիվը, հավելվածները, սարքի հետ առնչվող և սարքի տեղադրության տվյալները:\n\nՆաև ունեք VPN կապակցում, ինչը կարող է վերահսկել ձեր ցանցի գործունեությունը, այդ թվում նաև՝ էլեկտրոնային նամակները, հավելվածները և կայքերը:\n\nԼրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Աշխատանքային պրոֆիլի կառավարիչն է՝  <xliff:g id="ORGANIZATION">%1$s</xliff:g>:\n\nԱդմինիստրատորը կարող է վերահսկել ցանցում ունեցած գործունեությունը, այդ թվում՝ էլեկտրոնային նամակները, հավելվածները և վստահելի կայքերը:\n\nԼրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:\n\nՆաև ունեք VPN կապակցում, ինչը կարող է վերահսկել ձեր ցանցում կատարած գործողությունները:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index d4c1bdd9..088585a 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -366,9 +366,9 @@
     <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Profil kerja dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web aman.\n\nUntuk informasi selengkapnya, hubungi administrator."</string>
     <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Perangkat dikelola oleh:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nProfil kerja dikelola oleh:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nAdministrator dapat memantau aktivitas perangkat dan jaringan, termasuk email, aplikasi, dan situs web aman.\n\nUntuk informasi selengkapnya, hubungi administrator."</string>
     <string name="monitoring_description_vpn" msgid="912328761766161919">"Anda memberikan izin kepada aplikasi untuk menyiapkan sambungan VPN.\n\nAplikasi ini dapat memantau aktivitas perangkat dan jaringan, termasuk email, aplikasi, dan situs web aman."</string>
-    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data terkait perangkat, dan informasi lokasi perangkat.\n\nAnda tersambung ke VPN, yang dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web.\n\nUntuk informasi selengkapnya, hubungi administrator."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Profil kerja dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web aman.\n\nUntuk informasi selengkapnya, hubungi administrator.\n\nAnda juga tersambung ke VPN, yang dapat memantau aktivitas jaringan."</string>
-    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nProfil kerja dikelola oleh:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nAdministrator dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web aman.\n\nUntuk informasi selengkapnya, hubungi administrator.\n\nAnda juga tersambung ke VPN, yang dapat memantau aktivitas jaringan"</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator dapat memantau dan mengelola setelan, akses perusahaan, aplikasi, data terkait perangkat, dan informasi lokasi perangkat.\n\nAnda tersambung ke VPN yang dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web.\n\nUntuk informasi selengkapnya, hubungi administrator."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Profil kerja dikelola oleh <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web aman.\n\nUntuk informasi selengkapnya, hubungi administrator.\n\nAnda juga tersambung ke VPN yang dapat memantau aktivitas jaringan."</string>
+    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Perangkat dikelola oleh <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nProfil kerja dikelola oleh:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nAdministrator dapat memantau aktivitas jaringan, termasuk email, aplikasi, dan situs web aman.\n\nUntuk informasi selengkapnya, hubungi administrator.\n\nAnda juga tersambung ke VPN yang dapat memantau aktivitas jaringan"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Perangkat akan tetap terkunci hingga Anda membukanya secara manual"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Dapatkan pemberitahuan lebih cepat"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Lihat sebelum membuka kunci"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 5b36618..a5cd9ed 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -362,13 +362,13 @@
     <string name="monitoring_title" msgid="169206259253048106">"Желіні бақылау"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"VPN функциясын өшіру"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN желісін ажырату"</string>
-    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Құрылғыңызды басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз параметрлерді, корпоративтік қатынасты, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасуы туралы ақпаратты қадағалай алады. Қосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
-    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Сіздің жұмыс профиліңізді басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз электрондық пошта, қолданбалар және қауіпсіз сайттармен қоса желі әрекеттеріңізді қадағалай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
+    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Құрылғыңызды басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз параметрлерді, корпоративтік мүмкіндікті, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасуы туралы ақпаратты қадағалай алады. Қосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
+    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Сіздің жұмыс профиліңізді басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз электрондық пошта, қолданбалар және қауіпсіз сайттармен қоса, желідегі әрекеттеріңізді қадағалай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
     <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Құрылғыңызды басқаратын:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nЖұмыс профиліңізді басқаратын:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nСіздің әкімшіңіз электрондық пошта, қолданбалар және қауіпсіз сайттарды қосқанда, құрылғыңызды және желілік белсенділікті қадағалай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
-    <string name="monitoring_description_vpn" msgid="912328761766161919">"Сіз қолданбаға VPN байланысын орнатуға рұқсат бердіңіз.\n\nБұл қолданба электрондық пошта, қолданбалар және қауіпсіз сайттарды қосқанда, құрылғыны және желілік әрекеттерді қадағалай алады."</string>
-    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Құрылғыңызды басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз параметрлерді, корпоративтік қатынасты, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасуы туралы ақпаратты қадағалай алады.\n\nСіз электрондық пошта, қолданбалар және сайттарды қосқандағы желілік әрекеттеріңізді бақылай алатын VPN желісіне қосылдыңыз\n\nҚосымша ақпарат алу үшін, әкімшіге хабарласыңыз."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Сіздің жұмыс профиліңізді басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз электрондық пошта, қолданбалар және қауіпсіз сайттармен қоса желі әрекеттеріңізді қадағалай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз.\n\nСіз сондай-ақ сіздің жеке желілік әрекеттеріңізді бақылай алатын VPN желісіне қосылдыңыз."</string>
-    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Құрылғыңызды басқаратын:<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nЖұмыс профиліңізді басқаратын:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nСіздің әкімшіңіз электрондық пошта, қолданбалар және қауіпсіз сайттарды қосқанда, құрылғыңызды және желілік белсенділікті қадағалай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз.\n\nСіз сондай-ақ сіздің жеке желілік әрекеттеріңізді бақылай алатын VPN желісіне қосылдыңыз"</string>
+    <string name="monitoring_description_vpn" msgid="912328761766161919">"Сіз қолданбаға VPN байланысын орнатуға рұқсат бердіңіз.\n\nБұл қолданба электрондық пошта, қолданбалар және қауіпсіз сайттарды қосқанда, құрылғыны және желідегі әрекеттеріңізді қадағалай алады."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Құрылғыңызды басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз параметрлерді, корпоративтік мүмкіндікті, қолданбаларды, құрылғыңызбен байланысты деректерді және құрылғыңыздың орналасуы туралы ақпаратты қадағалай алады.\n\nСіз электрондық пошта, қолданбалар және сайттарды қосқандағы желілік әрекеттеріңізді бақылай алатын VPN желісіне қосылдыңыз.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Сіздің жұмыс профиліңізді басқаратын:<xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nСіздің әкімшіңіз электрондық пошта, қолданбалар және қауіпсіз сайттармен қоса, желідегі әрекеттеріңізді қадағалай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз.\n\nСіз сондай-ақ желідегі әрекеттеріңізді бақылай алатын VPN желісіне қосылдыңыз."</string>
+    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Құрылғыңызды басқаратын:<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nЖұмыс профиліңізді басқаратын:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nСіздің әкімшіңіз электрондық пошта, қолданбалар және қауіпсіз сайттарды қосқанда, құрылғыңызды және желідегі әрекеттеріңізді қадағалай алады.\n\nҚосымша ақпарат алу үшін әкімшіге хабарласыңыз.\n\nСіз сондай-ақ сіздің жеке желілік әрекеттеріңізді бақылай алатын VPN желісіне қосылдыңыз"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Қолмен бекітпесін ашқанша құрылғы бекітілген күйде қалады"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Хабарландыруларды тезірек алу"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Бекітпесін ашу алдында оларды көру"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index b0cc00a..97d6ba2 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -168,7 +168,7 @@
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"स्क्रीन बन्द गर्नुहोस्।"</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"सेटिङहरू"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"सारांश।"</string>
-    <string name="accessibility_desc_confirm" msgid="3446792278337969766">"निश्चित गर्नुहोस्"</string>
+    <string name="accessibility_desc_confirm" msgid="3446792278337969766">"पुष्टि गर्नुहोस्"</string>
     <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"प्रयोगकर्ता <xliff:g id="USER">%s</xliff:g>।"</string>
     <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>।"</string>
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"वाइफाइ बन्द गरियो।"</string>
@@ -303,7 +303,7 @@
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि माथि धिसार्नुहोस्"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string>
     <string name="zen_no_interruptions_with_warning" msgid="4396898053735625287">"कुनै रुकावट छैन। चेतावनी समेत छैन।"</string>
-    <string name="zen_priority_introduction" msgid="7253045784560169993">"अलार्म, अनुस्मारक, घटनाहरु, र तपाईँले निर्दिष्ट कल देखि बाहेक, आवाज र कंपनले तपाईँ व्याकुल हुनुहुने छैन।"</string>
+    <string name="zen_priority_introduction" msgid="7253045784560169993">"अलार्म, रिमाइन्डर, घटना, र तपाईँले निर्दिष्ट गर्नुहुने कलरहरू बाहेक, आवाज र कंपनले तपाईँ वाधा गर्ने छैन।"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"अनुकूलन गर्नुहोस्"</string>
     <string name="zen_no_interruptions" msgid="7970973750143632592">"कुनै रुकावटहरू छैन"</string>
     <string name="zen_important_interruptions" msgid="3477041776609757628">"प्राथमिकता रुकावटहरूमा मात्र"</string>
@@ -341,8 +341,8 @@
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"सुरु गर्नुहोस्"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"हो, जारी राख्नुहोस्"</string>
     <string name="guest_notification_title" msgid="1585278533840603063">"अतिथि प्रयोगकर्ता"</string>
-    <string name="guest_notification_text" msgid="7513706222848825467">"अनुप्रयोगहरू र डेटा मेटाउन अतिथिलाई निकाल्नु"</string>
-    <string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVE GUEST"</string>
+    <string name="guest_notification_text" msgid="7513706222848825467">"अनुप्रयोगहरू र डेटा मेटाउन अतिथिलाई निकाल्नुहोस्"</string>
+    <string name="guest_notification_remove_action" msgid="8820670703892101990">"अतिथिलाई हटाउनुहोस्"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"नयाँ प्रयोगकर्ता थप्नुहुन्छ?"</string>
     <string name="user_add_user_message_short" msgid="2161624834066214559">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nकुनै पनि प्रयोगकर्ताले सबै अन्य प्रयोगकर्ताहरूका लागि अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string>
     <string name="battery_saver_notification_title" msgid="237918726750955859">"ब्याट्रि सेभर चालु छ"</string>
@@ -362,13 +362,13 @@
     <string name="monitoring_title" msgid="169206259253048106">"सञ्जाल अनुगमन"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"VPN असक्षम गर्नुहोस्"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"विच्छेद VPN"</string>
-    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"तपाईँको उपकरण <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले सेटिङहरू, कर्पोरेट पहुँच, अनुप्रयोगहरू, आफ्नो उपकरण सम्बन्धित डेटा, र उपकरणको स्थानीय जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्छ। थप जानकारीको लागि, आफ्नो प्रशासक संग सम्पर्क राख्नुहोस्।"</string>
-    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"तपाईँको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासक इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्षम छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासक संग सम्पर्क राख्नुहोस्।"</string>
-    <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"तपाईँको उपकरण \n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n तपाईँको कार्य प्रोफाइल \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो उपकरण र सञ्जाल गतिविधि अनुगमन गर्न सक्छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासक संग सम्पर्क राख्नुहोस्।"</string>
-    <string name="monitoring_description_vpn" msgid="912328761766161919">"तपाईँले VPN जडान गर्न अनुप्रयोगलाई अनुमति दिनुभयो।\n\nयो अनुप्रयोगले तपाईको यन्त्र र नेटवर्क गतिविधि,  इमेलहरु सम्मिलित, अनुप्रयोगहरू र सुरक्षित वेबसाइटहरू।"</string>
-    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"तपाईँको उपकरण <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले सेटिङ्हरू, कर्पोरेट पहुँच, अनुप्रयोगहरू, आफ्नो उपकरण सम्बन्धित डेटा, र उपकरणको स्थानीय जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्छ।\n\nतपाईँ VPN संग जडित हुनुहुन्छ, जसले तपाईँको इमेल, अनुप्रयोगहरू, र वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्छ। \n\nथप जानकारीको लागि, आफ्नो प्रशासक संग सम्पर्क राख्नुहोस्।"</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"तपाईँको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्षम छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासक संग सम्पर्क राख्नुहोस्।\n\n तपाईँ VPN संग पनि जडित हुनुहुन्छ, जसले आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्छ।"</string>
-    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"तपाईँको उपकरण <xliff:g id="ORGANIZATION_0">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\nतपाईँको कार्य प्रोफाइल \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासक इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्षम छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासक संग सम्पर्क राख्नुहोस्।\n\n तपाईँ VPN संग पनि जडित हुनुहुन्छ, जसले आफ्नो व्यक्तिगत सञ्जाल गतिविधि अनुगमन गर्न सक्छ।"</string>
+    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"तपाईँको यन्त्र <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले सेटिङहरू, कर्पोरेट पहुँच, अनुप्रयोगहरू, आफ्नो उपकरण सम्बन्धित डेटा, र उपकरणको स्थानीय जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्छ। थप जानकारीको लागि, आफ्नो प्रशासकसँग सम्पर्क राख्नुहोस्।"</string>
+    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"तपाईँको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासक इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्षम छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासकससँग सम्पर्क राख्नुहोस्।"</string>
+    <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"तपाईँको यन्त्र \n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n तपाईँको कार्य प्रोफाइल \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो उपकरण र सञ्जाल गतिविधि अनुगमन गर्न सक्छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासकसँग सम्पर्क राख्नुहोस्।"</string>
+    <string name="monitoring_description_vpn" msgid="912328761766161919">"तपाईँले VPN जडान गर्न अनुप्रयोगलाई अनुमति दिनुभयो।\n\nयो अनुप्रयोगले तपाईको यन्त्र र नेटवर्क गतिविधि,  इमेलहरु सम्मिलित, अनुप्रयोगहरू र सुरक्षित वेबसाइटहरूका अनुगमन गर्नसक्छ।"</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"तपाईँको यन्त्र <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले सेटिङ्हरू, कर्पोरेट पहुँच, अनुप्रयोगहरू, आफ्नो उपकरण सम्बन्धित डेटा, र उपकरणको स्थानीय जानकारीको अनुगमन तथा व्यवस्थापन गर्न सक्छ।\n\nतपाईँ VPN सँग जडित हुनुहुन्छ, जसले तपाईँको इमेल, अनुप्रयोगहरू, र वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्छ। \n\nथप जानकारीको लागि, आफ्नो प्रशासकसँग सम्पर्क राख्नुहोस्।"</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"तपाईँको कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासकले इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्षम छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासकसँग सम्पर्क राख्नुहोस्।\n\n तपाईँ VPN सँग पनि जडित हुनुहुन्छ, जसले आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्छ।"</string>
+    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"तपाईँको यन्त्र <xliff:g id="ORGANIZATION_0">%1$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\nतपाईँको कार्य प्रोफाइल \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g> द्वारा व्यवस्थापन गरिन्छ।\n\n तपाईँको प्रशासक इमेल, अनुप्रयोगहरू, र सुरक्षित वेबसाइटहरू सहित आफ्नो सञ्जाल गतिविधि अनुगमन गर्न सक्षम छ।\n\n थप जानकारीको लागि, आफ्नो प्रशासकसँग सम्पर्क राख्नुहोस्।\n\n तपाईँ VPN सँग पनि जडित हुनुहुन्छ, जसले आफ्नो व्यक्तिगत सञ्जाल गतिविधि अनुगमन गर्न सक्छ।"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"तपाईँले नखोले सम्म उपकरण बन्द रहनेछ"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"छिटो सूचनाहरू प्राप्त गर्नुहोस्"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"तपाईँले अनलक गर्नअघि तिनीहरूलाई हेर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index fd40338..5b4c0cd 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -369,7 +369,7 @@
     <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Urządzeniem zarządza:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nTwoim profilem do pracy zarządza:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nAdministrator może monitorować Twoje urządzenie i aktywność w sieci, w tym e-maile, aplikacje i bezpieczne strony internetowe.\n\nSkontaktuj się z nim, by dowiedzieć się więcej."</string>
     <string name="monitoring_description_vpn" msgid="912328761766161919">"Nadałeś aplikacji uprawnienie do konfigurowania połączenia VPN.\n\nMoże ona monitorować Twoją aktywność na urządzeniu i w sieci, w tym e-maile, aplikacje i bezpieczne strony internetowe."</string>
     <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Urządzeniem zarządza <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator może monitorować ustawienia, firmowe uprawnienia dostępu, aplikacje, dane powiązane z tym urządzeniem i informacje o lokalizacji urządzenia oraz nimi zarządzać.\n\nMasz połączenie z siecią VPN, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe.\n\nAby uzyskać więcej informacji, skontaktuj się z administratorem."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Twoim profilem do pracy zarządza <xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nAdministrator może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i bezpieczne strony internetowe.\n\nSkontaktuj się z nim, by dowiedzieć się więcej.\n\nMasz także połączenie z siecią VPN, która może monitorować Twoją aktywność w sieci."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Twoim profilem do pracy zarządza <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministrator może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i bezpieczne strony internetowe.\n\nSkontaktuj się z nim, by dowiedzieć się więcej.\n\nMasz także połączenie z siecią VPN, która może monitorować Twoją aktywność w sieci."</string>
     <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Urządzeniem zarządza <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nTwoim profilem do pracy zarządza:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nAdministrator może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i bezpieczne strony.\n\nSkontaktuj się z nim, by dowiedzieć się więcej.\n\nMasz także połączenie z siecią VPN, która może monitorować Twoją osobistą aktywność w sieci"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Urządzenie pozostanie zablokowane, aż odblokujesz je ręcznie"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Szybszy dostęp do powiadomień"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 308feb5..58737ef 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -364,7 +364,7 @@
     <string name="disable_vpn" msgid="4435534311510272506">"Онемогући VPN"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"Прекини везу са VPN-ом"</string>
     <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Уређајем управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nАдминистратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима. Више информација потражите од администратора."</string>
-    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Профилом за Work profile управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nАдминистратор може да надгледа активности на мрежи, укључујући имејлове, апликације и безбедне веб-сајтове.\n\nВише информација потражите од администратора."</string>
+    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Профилом за Work управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nАдминистратор може да надгледа активности на мрежи, укључујући имејлове, апликације и безбедне веб-сајтове.\n\nВише информација потражите од администратора."</string>
     <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Уређајем управља:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nПрофилом за Work управља:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nАдминистратор може да надгледа активности на уређају и мрежи, укључујући имејлове, апликације и безбедне веб-сајтове.\n\nВише информација потражите од администратора."</string>
     <string name="monitoring_description_vpn" msgid="912328761766161919">"Дали сте дозволу апликацији да подешава VPN везу.\n\nТа апликација може да надгледа активности на уређају и мрежи, укључујући имејлове, апликације и безбедне веб-сајтове."</string>
     <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Уређајем управља <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nАдминистратор може да надгледа подешавања, корпоративни приступ, апликације, податке повезане са уређајем и информације о локацији уређаја, као и да управља њима.\n\nПовезани сте на VPN, који може да надгледа активности на мрежи, укључујући имејлове, апликације и безбедне веб-сајтове.\n\nВише информација потражите од администратора."</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 34f4f6e..2c29f24 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -362,13 +362,13 @@
     <string name="monitoring_title" msgid="169206259253048106">"Tarmoqlarni kuzatish"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"VPN tarmog‘ini o‘chirish"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN ulanishini uzish"</string>
-    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Qurilmangiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministratoringiz sozlamalar, korporativ ruxsat, ilovalar, qurilmangiz va qurilmangizning joylashuv ma’lumoti bilan bog‘liq ma’lumotlarni kuzata oladi va boshqara oladi. Ko‘proq ma’lumot olish uchun administrator bilan bog‘laning."</string>
-    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Sizning ish profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministratoringiz tarmoqdagi faoliyatingizni, jumladan, e-pochtalar, ilovalar va xavfsiz veb-saytlaringizni kuzata oladi.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning."</string>
-    <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Qurilmangiz \n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g> tomonidan boshqariladi.\nIsh profilingiz \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g> tomonidan boshqariladi.\n\nAdministratoringiz qurilmangiz va tarmoqdagi faoliyatingiz, jumladan, e-pochta, ilova va xavfsiz veb-saytlaringizni kuzata oladi.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning."</string>
-    <string name="monitoring_description_vpn" msgid="912328761766161919">"Siz ilovaga VPN ulanishini o‘rnatishga ruxsat bergansiz.\n\nUshbu ilova qurilmangiz va tarmoqdagi faoliyatingizni, jumladan, e-pochta, ilovalar va xavfsiz veb-saytlar bilan ishlashingizni kuzata oladi."</string>
-    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Qurilmangiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministratoringiz sozlamalar, korporativ ruxsat, ilovalar, qurilmangiz va qurilmangizning joylashuv ma’lumoti bilan bog‘liq ma’lumotlarni kuzata oladi va boshqara oladi.\n\nShuningdek, siz tarmoqdagi faoliyatingizni, jumladan, e-pochtal, ilova va veb-saytlaringizni kuzata oladigan VPN tarmog‘iga ham ulangansiz.\n\nKo‘proq ma’lumot olish uchun  administrator bilan bog‘laning."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Sizning ish profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministratoringiz tarmoqdagi faoliyatingizni, jumladan, e-pochta, ilova va xavfsiz veb-saytlar bilan ishlashingizni  kuzata oladi.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning.\n\nShuningdek, siz tarmoqdagi faoliyatingizni kuzata oladigan VPN tarmog‘iga ham ulangansiz."</string>
-    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Qurilmangiz <xliff:g id="ORGANIZATION_0">%1$s</xliff:g> tomonidan boshqariladi.\nIsh profilingiz \n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g> tomonidan boshqariladi.\n\nAdministratoringiz tarmoqdagi faoliyatingizni, jumladan, e-pochta, ilova va xavfsiz veb-saytlaringizni kuzata oladi.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning.\n\nShuningdek, siz shaxsiy tarmoqdagi faoliyatingizni kuzata oladigan VPN tarmog‘iga ham ulangansiz."</string>
+    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Qurilmangiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministrator sozlamalar, korporativ kirish huquqi, ilovalar, qurilmangizdagi ma’lumotlar, jumladan, joylashuv ma’lumotlari hamda unga bog‘liq boshqa ma’lumotlarni boshqarishi mumkin. Ko‘proq ma’lumot olish uchun administrator bilan bog‘laning."</string>
+    <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Ishchi profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministrator Internetdagi harakatlaringiz, jumladan, e-pochta, ilova va xavfsiz veb-saytlar bilan ishlashingizni kuzatishi mumkin.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning."</string>
+    <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Qurilmangiz <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\ntomonidan boshqariladi.\nIshchi profilingiz <xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\ntomonidan boshqariladi.\n\nAdministrator Internetdagi harakatlaringiz, jumladan, e-pochta, ilova va xavfsiz veb-saytlar bilan ishlashingizni kuzatishi mumkin.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning."</string>
+    <string name="monitoring_description_vpn" msgid="912328761766161919">"Siz ilovaga VPN tarmog‘iga ulanishga ruxsat bergansiz.\n\nUshbu ilova qurilmangiz va Internetdagi harakatlaringizni, jumladan, e-pochta, ilovalar va xavfsiz veb-saytlar bilan ishlashingizni kuzatishi mumkin."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Qurilmangiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministrator sozlamalar, korporativ kirish huquqi, ilovalar, qurilmangizdagi ma’lumotlar, jumladan, joylashuv ma’lumotlarini boshqarishi mumkin.\n\nShuningdek, siz Internetdagi harakatlaringizni, jumladan, e-pochta, ilova va veb-saytlar bilan ishlashingizni kuzata oladigan VPN tarmog‘iga ham ulangansiz.\n\nKo‘proq ma’lumot olish uchun  administrator bilan bog‘laning."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Sizning ishchi profilingiz <xliff:g id="ORGANIZATION">%1$s</xliff:g> tomonidan boshqariladi.\n\nAdministrator Internetdagi harakatlaringizni, jumladan, e-pochta, ilova va xavfsiz veb-saytlar bilan ishlashingizni  kuzata oladi.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning.\n\nShuningdek, siz tarmoqdagi faoliyatingizni kuzata oladigan VPN tarmog‘iga ham ulangansiz."</string>
+    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Qurilmangiz <xliff:g id="ORGANIZATION_0">%1$s</xliff:g> tomonidan boshqariladi.\nIshchi profilingiz <xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n tomonidan boshqariladi.\n\nAdministrator Internetdagi harakatlaringizni, jumladan, e-pochta, ilova va xavfsiz veb-saytlar bilan ishlashingizni kuzatishi mumkin.\n\nKo‘proq ma’lumot olish uchun administrator bilan bog‘laning.\n\nShuningdek, siz shaxsiy tarmoqdagi faoliyatingizni kuzata oladigan VPN tarmog‘iga ham ulangansiz."</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Qurilma qo‘lda qulfdan chiqarilmaguncha qulflangan holatda qoladi"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Bildirishnomalarni tezroq oling"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ularni qulfdan chiqarishdan oldin ko‘ring"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index da61e91..6e1e645 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -370,7 +370,7 @@
     <string name="monitoring_description_vpn" msgid="912328761766161919">"您已授权应用设置 VPN 连接。\n\n此应用可以监控您的设备和网络活动,包括收发电子邮件、使用应用和浏览安全网站。"</string>
     <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"您的设备由以下单位管理:<xliff:g id="ORGANIZATION">%1$s</xliff:g>。\n\n您单位的管理员可以监控和管理与此设备相关的设置、企业权限、应用、数据以及设备位置信息。\n\n您已连接到 VPN,此 VPN 也可以监控您的网络活动,包括收发电子邮件、使用应用和浏览网站。\n\n若要了解详情,请与您单位的管理员联系。"</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"您的工作资料由以下单位管理:<xliff:g id="ORGANIZATION">%1$s</xliff:g>。\n\n您单位的管理员可以监控您的网络活动,包括收发电子邮件、使用应用和浏览安全网站。\n\n若要了解详情,请与您单位的管理员联系。\n\n此外,您已连接到 VPN,此 VPN 也可以监控您的网络活动。"</string>
-    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"您的设备由以下单位管理:<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>。\n您的工作资料由以下设备管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>。\n\n您单位的管理员可以监控您的网络活动,包括收发电子邮件、使用应用和浏览安全网站。\n\n若要了解详情,请与您单位的管理员联系。\n\n此外,您已连接到 VPN,此 VPN 也可以监控您的个人网络活动"</string>
+    <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"您的设备由以下单位管理:<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>。\n您的工作资料由以下单位管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>。\n\n您单位的管理员可以监控您的网络活动,包括收发电子邮件、使用应用和浏览安全网站。\n\n若要了解详情,请与您单位的管理员联系。\n\n此外,您已连接到 VPN,此 VPN 也可以监控您的个人网络活动"</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"在您手动解锁之前,设备会保持锁定状态"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"更快捷地查看通知"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"无需解锁即可查看通知"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 1f1455a..7a108ed 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -128,7 +128,7 @@
     <color name="screen_pinning_request_window_bg">#80000000</color>
 
     <color name="segmented_button_selected">#FFFFFFFF</color>
-    <color name="segmented_button_unselected">#B3B0BEC5</color><!-- 70% blue grey 200 -->
+    <color name="segmented_button_unselected">#FFB0BEC5</color><!-- blue grey 200 -->
 
     <color name="dark_mode_icon_color_single_tone">#99000000</color>
     <color name="dark_mode_icon_color_dual_tone_background">#3d000000</color>
@@ -139,4 +139,6 @@
     <color name="light_mode_icon_color_dual_tone_fill">#ffffff</color>
 
     <color name="zen_introduction_message_background">#ff009688</color><!-- deep teal 500 -->
+    <color name="volume_icon_color">#ffffffff</color>
+    <color name="volume_settings_icon_color">#7fffffff</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 2e44547..6e79423 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -150,7 +150,7 @@
     <integer name="heads_up_notification_minimum_time">2000</integer>
 
     <!-- milliseconds before the heads up notification accepts touches. -->
-    <integer name="heads_up_sensitivity_delay">700</integer>
+    <integer name="touch_acceptance_delay">700</integer>
 
     <!-- The duration in seconds to wait before the dismiss buttons are shown. -->
     <integer name="recents_task_bar_dismiss_delay_seconds">1</integer>
@@ -293,5 +293,9 @@
 
     <!-- Duration of the full carrier network change icon animation. -->
     <integer name="carrier_network_change_anim_time">3000</integer>
+
+    <!-- Duration of the expansion animation in the volume dialog -->
+    <item name="volume_expand_animation_duration" type="integer">300</item>
+
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6e59029..a0ef5e2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -573,4 +573,13 @@
 
     <!-- Minimum margin of the notification panel on the side, when being positioned dynamically -->
     <dimen name="notification_panel_min_side_margin">48dp</dimen>
+
+    <!-- Vertical spacing between multiple volume slider rows -->
+    <dimen name="volume_slider_interspacing">8dp</dimen>
+
+    <!-- Volume dialog vertical offset from the top of the screen -->
+    <dimen name="volume_offset_top">0dp</dimen>
+
+    <!-- Standard image button size for volume dialog buttons -->
+    <dimen name="volume_button_size">48dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f12fd0c..8b50774 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -439,7 +439,7 @@
     <!-- Content description of the do not disturb tile in quick settings when on in priority (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_priority_on">Do not disturb on, priority only.</string>
     <!-- Content description of the do not disturb tile in quick settings when on in none (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_quick_settings_dnd_none_on">Do not disturb on, no interruptions.</string>
+    <string name="accessibility_quick_settings_dnd_none_on">Do not disturb on, total silence.</string>
     <!-- Content description of the do not disturb tile in quick settings when on in alarms only (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_alarms_on">Do not disturb on, alarms only.</string>
      <!-- Content description of the do not disturb tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -576,8 +576,8 @@
     <string name="quick_settings_dnd_priority_label">Priority only</string>
     <!-- QuickSettings: Do not disturb - Alarms only [CHAR LIMIT=NONE] -->
     <string name="quick_settings_dnd_alarms_label">Alarms only</string>
-    <!-- QuickSettings: Do not disturb - No interruptions [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_dnd_none_label">No interruptions</string>
+    <!-- QuickSettings: Do not disturb - Total silence [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_dnd_none_label">Total silence</string>
     <!-- QuickSettings: Bluetooth [CHAR LIMIT=NONE] -->
     <string name="quick_settings_bluetooth_label">Bluetooth</string>
     <!-- QuickSettings: Bluetooth (Multiple) [CHAR LIMIT=NONE] -->
@@ -725,32 +725,14 @@
     <!-- Description of the left direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
     <string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
 
-    <!-- Zen mode: No interruptions title, with a warning about alarms. [CHAR LIMIT=60] -->
-    <string name="zen_no_interruptions_with_warning">No interruptions. Not even alarms.</string>
-
     <!-- Zen mode: Priority only introduction message on first use -->
-    <string name="zen_priority_introduction">You won\'t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify.</string>
+    <string name="zen_priority_introduction">You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events, and callers you specify.</string>
 
     <!-- Zen mode: Priority only customization button label -->
     <string name="zen_priority_customize_button">Customize</string>
 
-    <!-- Zen mode: No interruptions. [CHAR LIMIT=40] -->
-    <string name="zen_no_interruptions">No interruptions</string>
-
-    <!-- Zen mode: Only important interruptions. [CHAR LIMIT=40] -->
-    <string name="zen_important_interruptions">Priority interruptions only</string>
-
-    <!-- Zen mode: Only alarms. [CHAR LIMIT=40] -->
-    <string name="zen_alarms">Alarms only</string>
-
-    <!-- Zen mode: Next alarm information - just a time. [CHAR LIMIT=40] -->
-    <string name="zen_alarm_information_time">Your next alarm is at <xliff:g id="alarm_time" example="5:00 PM">%s</xliff:g></string>
-
-    <!-- Zen mode: Next alarm information - day and time. [CHAR LIMIT=40] -->
-    <string name="zen_alarm_information_day_time">Your next alarm is <xliff:g id="alarm_day_and_time" example="Fri 5:00 PM">%s</xliff:g></string>
-
-    <!-- Zen mode: Next alarm warning. [CHAR LIMIT=40] -->
-    <string name="zen_alarm_warning">You won\'t hear your alarm at <xliff:g id="alarm_time" example="5:00 PM">%s</xliff:g></string>
+    <!-- Zen mode: Total silence introduction message on first use -->
+    <string name="zen_silence_introduction">This blocks ALL sounds and vibrations, including from alarms, music, videos, and games. You’ll still be able to make phone calls.</string>
 
     <!-- Text for overflow card on Keyguard when there is not enough space for all notifications on Keyguard. [CHAR LIMIT=1] -->
     <string name="keyguard_more_overflow_text">+<xliff:g id="number_of_notifications" example="5">%d</xliff:g></string>
@@ -771,7 +753,7 @@
     <string name="camera_hint">Swipe left for camera</string>
 
     <!-- Interruption level: None. [CHAR LIMIT=20] -->
-    <string name="interruption_level_none">No interruptions</string>
+    <string name="interruption_level_none">Total silence</string>
 
     <!-- Interruption level: Priority. [CHAR LIMIT=20] -->
     <string name="interruption_level_priority">Priority only</string>
@@ -779,11 +761,8 @@
     <!-- Interruption level: Alarms only. [CHAR LIMIT=20] -->
     <string name="interruption_level_alarms">Alarms only</string>
 
-    <!-- Interruption level: All. [CHAR LIMIT=20] -->
-    <string name="interruption_level_all">All</string>
-
     <!-- Interruption level: None.  Optimized for narrow two-line display. [CHAR LIMIT=20] -->
-    <string name="interruption_level_none_twoline">No\ninterruptions</string>
+    <string name="interruption_level_none_twoline">Total\nsilence</string>
 
     <!-- Interruption level: Priority.  Optimized for narrow two-line display. [CHAR LIMIT=20] -->
     <string name="interruption_level_priority_twoline">Priority\nonly</string>
@@ -953,6 +932,9 @@
     <!-- Accessibility string for current zen mode and selected exit condition. A template that simply concatenates existing mode string and the current condition description. [CHAR LIMIT=20] -->
     <string name="zen_mode_and_condition"><xliff:g id="zen_mode" example="Priority interruptions only">%1$s</xliff:g>. <xliff:g id="exit_condition" example="For one hour">%2$s</xliff:g></string>
 
+    <!-- Button label for ending zen mode in the volume dialog -->
+    <string name="volume_zen_end_now">End now</string>
+
     <!-- Screen pinning dialog title. -->
     <string name="screen_pinning_title">Screen is pinned</string>
     <!-- Screen pinning dialog description. -->
@@ -988,9 +970,26 @@
     <!-- VolumeUI restoration notification: text -->
     <string name="volumeui_notification_text">Touch to restore the original.</string>
 
-    <!-- Volume dialog zen toggle switch title -->
-    <string name="volume_zen_switch_text" translatable="false">@*android:string/zen_mode_feature_name</string>
-
     <!-- Toast shown when user unlocks screen and managed profile activity is in the foreground -->
     <string name="managed_profile_foreground_toast">You are in the Work profile</string>
+
+    <string-array name="volume_stream_titles" translatable="false">
+        <item>Voice calls</item> <!-- STREAM_VOICE_CALL -->
+        <item>System</item> <!-- STREAM_SYSTEM -->
+        <item>Notifications</item> <!-- STREAM_RING -->
+        <item>Media</item> <!-- STREAM_MUSIC -->
+        <item>Alarms</item> <!-- STREAM_ALARM -->
+        <item></item> <!-- STREAM_NOTIFICATION -->
+        <item>Bluetooth calls</item> <!-- STREAM_BLUETOOTH_SCO -->
+        <item></item> <!-- STREAM_SYSTEM_ENFORCED -->
+        <item></item> <!-- STREAM_DTMF -->
+        <item></item> <!-- STREAM_TTS -->
+    </string-array>
+
+    <string name="volume_stream_muted" translatable="false">%s silent</string>
+    <string name="volume_stream_vibrate" translatable="false">%s vibrate</string>
+    <string name="volume_stream_suppressed" translatable="false">%1$s silent — %2$s</string>
+    <string name="volume_stream_muted_dnd" translatable="false">%s silent — Total silence</string>
+    <string name="volume_stream_limited_dnd" translatable="false">%s — Priority only</string>
+    <string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ef2e6f3..c058d44 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -165,7 +165,7 @@
     </style>
 
     <style name="TextAppearance.QS.SegmentedButton">
-        <item name="android:textSize">14sp</item>
+        <item name="android:textSize">16sp</item>
     </style>
 
     <style name="TextAppearance.QS.DataUsage">
@@ -262,4 +262,31 @@
         <item name="fillColor">@color/dark_mode_icon_color_dual_tone_fill</item>
         <item name="singleToneColor">@color/dark_mode_icon_color_single_tone</item>
     </style>
+
+    <style name="TextAppearance.Volume">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#ffffffff</item>
+        <item name="android:fontFamily">sans-serif</item>
+    </style>
+
+    <style name="TextAppearance.Volume.ZenSummary">
+        <item name="android:textSize">14sp</item>
+        <item name="android:fontFamily">sans-serif-medium</item>
+    </style>
+
+    <style name="TextAppearance.Volume.ZenDetail">
+        <item name="android:textSize">14sp</item>
+        <item name="android:fontFamily">sans-serif</item>
+        <item name="android:textColor">#ffb0b3c5</item>
+    </style>
+
+    <style name="VolumeDialogAnimations">
+        <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
+        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
+    </style>
+
+    <style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless">
+        <item name="android:background">@drawable/btn_borderless_rect</item>
+    </style>
+
 </resources>
diff --git a/packages/SystemUI/res/values/volume.xml b/packages/SystemUI/res/values/volume.xml
deleted file mode 100644
index f516104..0000000
--- a/packages/SystemUI/res/values/volume.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item name="volume_expand_animation_duration" type="integer">300</item>
-
-    <color name="volume_icon_color">#ffffffff</color>
-    <color name="volume_settings_icon_color">#7fffffff</color>
-
-    <dimen name="volume_slider_interspacing">2dp</dimen>
-    <dimen name="volume_offset_top">0dp</dimen>
-    <dimen name="volume_button_size">48dp</dimen>
-
-    <item name="volume_secondary_alpha" format="float" type="dimen">0.3</item>
-
-    <style name="VolumeDialogAnimations">
-        <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
-        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
-    </style>
-
-    <style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless">
-        <item name="android:background">@drawable/btn_borderless_rect</item>
-    </style>
-
-    <style name="TextAppearance" />
-
-    <style name="TextAppearance.Volume">
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#ffffffff</item>
-        <item name="android:fontFamily">sans-serif</item>
-    </style>
-
-    <style name="TextAppearance.Volume.ZenSwitch">
-        <item name="android:textSize">16sp</item>
-        <item name="android:fontFamily">sans-serif-medium</item>
-    </style>
-
-    <style name="TextAppearance.Volume.ZenSwitchSummary">
-        <item name="android:textSize">14sp</item>
-        <item name="android:fontFamily">sans-serif-medium</item>
-    </style>
-
-    <style name="TextAppearance.Volume.ZenSwitchDetail">
-        <item name="android:textSize">14sp</item>
-        <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textColor">#ffb0b3c5</item>
-    </style>
-
-    <string-array name="volume_stream_titles" translatable="false">
-        <item>Voice calls</item> <!-- STREAM_VOICE_CALL -->
-        <item>System</item> <!-- STREAM_SYSTEM -->
-        <item>Notifications</item> <!-- STREAM_RING -->
-        <item>Media</item> <!-- STREAM_MUSIC -->
-        <item>Alarms</item> <!-- STREAM_ALARM -->
-        <item></item> <!-- STREAM_NOTIFICATION -->
-        <item>Bluetooth calls</item> <!-- STREAM_BLUETOOTH_SCO -->
-        <item></item> <!-- STREAM_SYSTEM_ENFORCED -->
-        <item></item> <!-- STREAM_DTMF -->
-        <item></item> <!-- STREAM_TTS -->
-    </string-array>
-
-    <string name="volume_dnd_is_on" translatable="false">Do not disturb is on</string>
-    <string name="volume_turn_off" translatable="false">Turn off</string>
-    <string name="volume_stream_muted" translatable="false">%s silent</string>
-    <string name="volume_stream_vibrate" translatable="false">%s vibrate</string>
-    <string name="volume_stream_suppressed" translatable="false">%1$s silent — %2$s</string>
-    <string name="volume_stream_muted_dnd" translatable="false">%s silent — No interruptions</string>
-    <string name="volume_stream_limited_dnd" translatable="false">%s — Priority only</string>
-    <string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string>
-    <string name="volume_dnd_ends_in" translatable="false">Do not disturb ends in %s</string>
-    <string name="volume_dnd_ends_at" translatable="false">Do not disturb ends at %s</string>
-    <string name="volume_end_now" translatable="false">End now</string>
-
-</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 0d331d1..3fbc76b 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -225,23 +225,23 @@
         mSubpixelSmoothingRight = context.getResources().getFraction(
                 R.fraction.battery_subpixel_smoothing_right, 1, 1);
 
-        mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mFramePaint = new Paint();
         mFramePaint.setColor(frameColor);
         mFramePaint.setDither(true);
         mFramePaint.setStrokeWidth(0);
         mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE);
 
-        mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mBatteryPaint = new Paint();
         mBatteryPaint.setDither(true);
         mBatteryPaint.setStrokeWidth(0);
         mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE);
 
-        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mTextPaint = new Paint();
         Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
         mTextPaint.setTypeface(font);
         mTextPaint.setTextAlign(Paint.Align.CENTER);
 
-        mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mWarningTextPaint = new Paint();
         mWarningTextPaint.setColor(mColors[1]);
         font = Typeface.create("sans-serif", Typeface.BOLD);
         mWarningTextPaint.setTypeface(font);
@@ -249,7 +249,7 @@
 
         mChargeColor = context.getColor(R.color.batterymeter_charge_color);
 
-        mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mBoltPaint = new Paint();
         mBoltPaint.setColor(context.getColor(R.color.batterymeter_bolt_color));
         mBoltPoints = loadBoltPoints(res);
 
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
index d2ce94b..a584cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
+++ b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
@@ -5,7 +5,7 @@
 # ---------------------------
 # PhoneStatusBar.java
 # ---------------------------
-36000 sysui_statusbar_touch (type|1),(x|1),(y|1),(enabled|1)
+36000 sysui_statusbar_touch (type|1),(x|1),(y|1),(disable1|1),(disable2|1)
 36001 sysui_heads_up_status (key|3),(visible|1)
 36002 sysui_fullscreen_notification (key|3)
 36003 sysui_heads_up_escalation (key|3)
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 68b1968..29d2a01 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -37,8 +37,10 @@
         Key.DND_TILE_VISIBLE,
         Key.DND_TILE_COMBINED_ICON,
         Key.DND_CONFIRMED_PRIORITY_INTRODUCTION,
+        Key.DND_CONFIRMED_SILENCE_INTRODUCTION,
         Key.DND_FAVORITE_BUCKET_INDEX,
         Key.DND_NONE_SELECTED,
+        Key.DND_FAVORITE_ZEN,
     })
     public @interface Key {
         String SEARCH_APP_WIDGET_ID = "searchAppWidgetId";
@@ -48,8 +50,10 @@
         String DND_TILE_VISIBLE = "DndTileVisible";
         String DND_TILE_COMBINED_ICON = "DndTileCombinedIcon";
         String DND_CONFIRMED_PRIORITY_INTRODUCTION = "DndConfirmedPriorityIntroduction";
+        String DND_CONFIRMED_SILENCE_INTRODUCTION = "DndConfirmedSilenceIntroduction";
         String DND_FAVORITE_BUCKET_INDEX = "DndCountdownMinuteIndex";
         String DND_NONE_SELECTED = "DndNoneSelected";
+        String DND_FAVORITE_ZEN = "DndFavoriteZen";
     }
 
     public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7b555fc..6479dc5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -539,10 +539,11 @@
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
 
         mLockPatternUtils = new LockPatternUtils(mContext);
-        mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
+        KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser());
 
         // Assume keyguard is showing (unless it's disabled) until we know for sure...
-        setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled());
+        setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled(
+                KeyguardUpdateMonitor.getCurrentUser()));
         mTrustManager.reportKeyguardShowingChanged();
 
         mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
@@ -623,8 +624,10 @@
             // Lock immediately based on setting if secure (user has a pin/pattern/password).
             // This also "locks" the device when not secure to provide easy access to the
             // camera while preventing unwanted input.
+            int currentUser = KeyguardUpdateMonitor.getCurrentUser();
             final boolean lockImmediately =
-                mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
+                mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
+                        || !mLockPatternUtils.isSecure(currentUser);
 
             notifyScreenOffLocked();
 
@@ -670,7 +673,7 @@
 
         // From DevicePolicyAdmin
         final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
-                .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser());
+                .getMaximumTimeToLock(null, KeyguardUpdateMonitor.getCurrentUser());
 
         long timeout;
         if (policyTimeout > 0) {
@@ -719,7 +722,8 @@
     }
 
     private void maybeSendUserPresentBroadcast() {
-        if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()) {
+        if (mSystemReady && mLockPatternUtils.isLockScreenDisabled(
+                KeyguardUpdateMonitor.getCurrentUser())) {
             // Lock screen is disabled because the user has set the preference to "None".
             // In this case, send out ACTION_USER_PRESENT here instead of in
             // handleKeyguardDone()
@@ -733,7 +737,7 @@
      */
     public void onDreamingStarted() {
         synchronized (this) {
-            if (mScreenOn && mLockPatternUtils.isSecure()) {
+            if (mScreenOn && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
                 doKeyguardLaterLocked();
             }
         }
@@ -974,12 +978,13 @@
             return;
         }
 
-        if (mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
+        if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
+                && !lockedOrMissing) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
             return;
         }
 
-        if (mLockPatternUtils.checkVoldPassword()) {
+        if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
             if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
             // Without this, settings is not enabled until the lock screen first appears
             setShowingLocked(false);
@@ -1072,7 +1077,7 @@
     }
 
     public boolean isSecure() {
-        return mLockPatternUtils.isSecure()
+        return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())
             || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
     }
 
@@ -1083,7 +1088,7 @@
      * @param newUserId The id of the incoming user.
      */
     public void setCurrentUser(int newUserId) {
-        mLockPatternUtils.setCurrentUser(newUserId);
+        KeyguardUpdateMonitor.setCurrentUser(newUserId);
     }
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -1213,7 +1218,7 @@
     private void sendUserPresentBroadcast() {
         synchronized (this) {
             if (mBootCompleted) {
-                final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
+                final UserHandle currentUser = new UserHandle(KeyguardUpdateMonitor.getCurrentUser());
                 final UserManager um = (UserManager) mContext.getSystemService(
                         Context.USER_SERVICE);
                 List <UserInfo> userHandles = um.getProfiles(currentUser.getIdentifier());
@@ -1393,14 +1398,9 @@
             updateActivityLockScreenState();
             adjustStatusBarLocked();
             sendUserPresentBroadcast();
-            maybeStopListeningForFingerprint();
         }
     }
 
-    private void maybeStopListeningForFingerprint() {
-        mUpdateMonitor.stopListeningForFingerprint();
-    }
-
     private void adjustStatusBarLocked() {
         if (mStatusBarManager == null) {
             mStatusBarManager = (StatusBarManager)
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 6ce63d6..5145bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -37,7 +37,11 @@
 
 /** Quick settings tile: Do not disturb **/
 public class DndTile extends QSTile<QSTile.BooleanState> {
-    private static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+    private static final Intent ZEN_SETTINGS =
+            new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+
+    private static final Intent ZEN_PRIORITY_SETTINGS =
+            new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
 
     private static final String ACTION_SET_VISIBLE = "com.android.systemui.dndtile.SET_VISIBLE";
     private static final String EXTRA_VISIBLE = "visible";
@@ -87,7 +91,9 @@
         if (mState.value) {
             mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
         } else {
-            mController.setZen(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, TAG);
+            int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
+            mController.setZen(zen, null, TAG);
+            refreshState(zen); // this one's optimistic
             showDetail(true);
         }
     }
@@ -209,8 +215,8 @@
                             R.layout.zen_mode_panel, parent, false);
             if (convertView == null) {
                 zmp.init(mController);
-                zmp.setEmbedded(true);
                 zmp.addOnAttachStateChangeListener(this);
+                zmp.setCallback(mZenModePanelCallback);
             }
             return zmp;
         }
@@ -225,4 +231,22 @@
             mShowingDetail = false;
         }
     }
+
+    private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
+        @Override
+        public void onPrioritySettings() {
+            mHost.startSettingsActivity(ZEN_PRIORITY_SETTINGS);
+        }
+
+        @Override
+        public void onInteraction() {
+            // noop
+        }
+
+        @Override
+        public void onExpanded(boolean expanded) {
+            // noop
+        }
+    };
+
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index e542264..26c3b4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -87,6 +87,7 @@
 import com.android.internal.statusbar.StatusBarIconList;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SwipeHelper;
@@ -581,7 +582,7 @@
         createAndAddWindows();
 
         mSettingsObserver.onChange(false); // set up
-        disable(switches[0], false /* animate */);
+        disable(switches[0], switches[6], false /* animate */);
         setSystemUiVisibility(switches[1], 0xffffffff);
         topAppWindowChanged(switches[2] != 0);
         // StatusBarManagerService has a back up of IME token and it's restored here.
@@ -639,7 +640,7 @@
                 Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 1)) {
             Log.d(TAG, "user hasn't seen notification about hidden notifications");
             final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
-            if (!lockPatternUtils.isSecure()) {
+            if (!lockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
                 Log.d(TAG, "insecure lockscreen, skipping notification");
                 Settings.Secure.putInt(mContext.getContentResolver(),
                         Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
@@ -708,18 +709,6 @@
         mNotificationListener.setNotificationsShown(keys);
     }
 
-    protected void setNotificationsShownAll() {
-        ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
-        final int N = activeNotifications.size();
-
-        String[] keys = new String[N];
-        for (int i = 0; i < N; i++) {
-            NotificationData.Entry entry = activeNotifications.get(i);
-            keys[i] = entry.key;
-        }
-        setNotificationsShown(keys);
-    }
-
     protected boolean isCurrentProfile(int userId) {
         synchronized (mCurrentProfiles) {
             return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
@@ -795,7 +784,8 @@
     protected void applyColorsAndBackgrounds(StatusBarNotification sbn,
             NotificationData.Entry entry) {
 
-        if (entry.expanded.getId() != com.android.internal.R.id.status_bar_latest_event_content) {
+        if (entry.getContentView().getId()
+                != com.android.internal.R.id.status_bar_latest_event_content) {
             // Using custom RemoteViews
             if (entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
                     && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP) {
@@ -820,8 +810,9 @@
 
     public boolean isMediaNotification(NotificationData.Entry entry) {
         // TODO: confirm that there's a valid media key
-        return entry.expandedBig != null &&
-               entry.expandedBig.findViewById(com.android.internal.R.id.media_actions) != null;
+        return entry.getExpandedContentView() != null &&
+               entry.getExpandedContentView()
+                       .findViewById(com.android.internal.R.id.media_actions) != null;
     }
 
     // The gear button in the guts that links to the app's own notification settings
@@ -1145,9 +1136,9 @@
     }
 
     /**
-     * if the interrupting notification had a fullscreen intent, fire it now.
+     * If there is an active heads-up notification and it has a fullscreen intent, fire it now.
      */
-    public abstract void escalateHeadsUp();
+    public abstract void maybeEscalateHeadsUp();
 
     /**
      * Save the current "public" (locked and secure) state of the lockscreen.
@@ -1348,8 +1339,8 @@
         View publicViewLocal = null;
         if (publicNotification != null) {
             try {
-                publicViewLocal = publicNotification.contentView.apply(mContext, contentContainerPublic,
-                        mOnClickHandler);
+                publicViewLocal = publicNotification.contentView.apply(mContext,
+                        contentContainerPublic, mOnClickHandler);
 
                 if (publicViewLocal != null) {
                     publicViewLocal.setIsRootNamespace(true);
@@ -1456,9 +1447,7 @@
         entry.row = row;
         entry.row.setHeightRange(mRowMinHeight, maxHeight);
         entry.row.setOnActivatedListener(this);
-        entry.expanded = contentViewLocal;
-        entry.expandedPublic = publicViewLocal;
-        entry.setBigContentView(bigContentViewLocal);
+        entry.row.setExpandable(bigContentViewLocal != null);
 
         applyColorsAndBackgrounds(sbn, entry);
 
@@ -1547,12 +1536,13 @@
 
         // See if we have somewhere to put that remote input
         if (remoteInput != null) {
-            if (entry.expandedBig != null) {
-                inflateRemoteInput(entry.expandedBig, remoteInput, actions);
+            View bigContentView = entry.getExpandedContentView();
+            if (bigContentView != null) {
+                inflateRemoteInput(bigContentView, remoteInput, actions);
             }
-            View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
-            if (headsUpChild != null) {
-                inflateRemoteInput(headsUpChild, remoteInput, actions);
+            View headsUpContentView = entry.getHeadsUpContentView();
+            if (headsUpContentView != null) {
+                inflateRemoteInput(headsUpContentView, remoteInput, actions);
             }
         }
 
@@ -1701,7 +1691,6 @@
                 boolean clearNotificationEffects =
                         (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
                 mBarService.onPanelRevealed(clearNotificationEffects);
-                setNotificationsShownAll();
             } else {
                 mBarService.onPanelHidden();
             }
@@ -1895,15 +1884,14 @@
             logUpdate(entry, n);
         }
         boolean applyInPlace = shouldApplyInPlace(entry, n);
-        final boolean shouldInterrupt = shouldInterrupt(notification);
-        final boolean alertAgain = alertAgain(entry, n);
+        boolean shouldInterrupt = shouldInterrupt(notification);
+        boolean alertAgain = alertAgain(entry, n);
 
         entry.notification = notification;
         mGroupManager.onEntryUpdated(entry, entry.notification);
 
         boolean updateSuccessful = false;
         if (applyInPlace) {
-            // We can just reapply the notifications in place
             if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
             try {
                 if (entry.icon != null) {
@@ -1924,7 +1912,7 @@
                 updateSuccessful = true;
             }
             catch (RuntimeException e) {
-                // It failed to add cleanly.  Log, and remove the view from the panel.
+                // It failed to apply cleanly.
                 Log.w(TAG, "Couldn't reapply views for package " + n.contentView.getPackage(), e);
             }
         }
@@ -1948,11 +1936,12 @@
         // swipe-dismissable)
         updateNotificationVetoButton(entry.row, notification);
 
-        // Is this for you?
-        boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
-        if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+        if (DEBUG) {
+            // Is this for you?
+            boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
+            Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+        }
 
-        // Recalculate the position of the sliding windows and the titles.
         setAreThereNotifications();
     }
 
@@ -1963,7 +1952,7 @@
         StatusBarNotification oldNotification = oldEntry.notification;
         Log.d(TAG, "old notification: when=" + oldNotification.getNotification().when
                 + " ongoing=" + oldNotification.isOngoing()
-                + " expanded=" + oldEntry.expanded
+                + " expanded=" + oldEntry.getContentView()
                 + " contentView=" + oldNotification.getNotification().contentView
                 + " bigContentView=" + oldNotification.getNotification().bigContentView
                 + " publicView=" + oldNotification.getNotification().publicVersion
@@ -1976,7 +1965,8 @@
     }
 
     /**
-     * @return whether we can just reapply the RemoteViews in place when it is updated
+     * @return whether we can just reapply the RemoteViews from a notification in-place when it is
+     * updated
      */
     private boolean shouldApplyInPlace(Entry entry, Notification n) {
         StatusBarNotification oldNotification = entry.notification;
@@ -1994,15 +1984,15 @@
         final Notification publicNotification = n.publicVersion;
         final RemoteViews publicContentView = publicNotification != null
                 ? publicNotification.contentView : null;
-        boolean contentsUnchanged = entry.expanded != null
+        boolean contentsUnchanged = entry.getContentView() != null
                 && contentView.getPackage() != null
                 && oldContentView.getPackage() != null
                 && oldContentView.getPackage().equals(contentView.getPackage())
                 && oldContentView.getLayoutId() == contentView.getLayoutId();
         // large view may be null
         boolean bigContentsUnchanged =
-                (entry.getBigContentView() == null && bigContentView == null)
-                || ((entry.getBigContentView() != null && bigContentView != null)
+                (entry.getExpandedContentView() == null && bigContentView == null)
+                || ((entry.getExpandedContentView() != null && bigContentView != null)
                     && bigContentView.getPackage() != null
                     && oldBigContentView.getPackage() != null
                     && oldBigContentView.getPackage().equals(bigContentView.getPackage())
@@ -2034,12 +2024,12 @@
                 : null;
 
         // Reapply the RemoteViews
-        contentView.reapply(mContext, entry.expanded, mOnClickHandler);
-        if (bigContentView != null && entry.getBigContentView() != null) {
-            bigContentView.reapply(mContext, entry.getBigContentView(),
+        contentView.reapply(mContext, entry.getContentView(), mOnClickHandler);
+        if (bigContentView != null && entry.getExpandedContentView() != null) {
+            bigContentView.reapply(mContext, entry.getExpandedContentView(),
                     mOnClickHandler);
         }
-        View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
+        View headsUpChild = entry.getHeadsUpContentView();
         if (headsUpContentView != null && headsUpChild != null) {
             headsUpContentView.reapply(mContext, headsUpChild, mOnClickHandler);
         }
@@ -2062,7 +2052,7 @@
     }
 
     protected void notifyHeadsUpScreenOff() {
-        escalateHeadsUp();
+        maybeEscalateHeadsUp();
     }
 
     private boolean alertAgain(Entry oldEntry, Notification newNotification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 7aa9a90..4542054 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -83,7 +83,7 @@
         public void updateIcon(String slot, int index, int viewIndex,
                 StatusBarIcon old, StatusBarIcon icon);
         public void removeIcon(String slot, int index, int viewIndex);
-        public void disable(int state, boolean animate);
+        public void disable(int state1, int state2, boolean animate);
         public void animateExpandNotificationsPanel();
         public void animateCollapsePanels(int flags);
         public void animateExpandSettingsPanel();
@@ -127,10 +127,10 @@
         }
     }
 
-    public void disable(int state) {
+    public void disable(int state1, int state2) {
         synchronized (mList) {
             mHandler.removeMessages(MSG_DISABLE);
-            mHandler.obtainMessage(MSG_DISABLE, state, 0, null).sendToTarget();
+            mHandler.obtainMessage(MSG_DISABLE, state1, state2, null).sendToTarget();
         }
     }
 
@@ -304,7 +304,7 @@
                     break;
                 }
                 case MSG_DISABLE:
-                    mCallbacks.disable(msg.arg1, true /* animate */);
+                    mCallbacks.disable(msg.arg1, msg.arg2, true /* animate */);
                     break;
                 case MSG_EXPAND_NOTIFICATIONS:
                     mCallbacks.animateExpandNotificationsPanel();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index cb8217e..9ef495d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -84,7 +84,6 @@
     private ExpansionLogger mLogger;
     private String mLoggingKey;
     private boolean mWasReset;
-
     private NotificationGuts mGuts;
     private StatusBarNotification mStatusBarNotification;
     private boolean mIsHeadsUp;
@@ -102,6 +101,7 @@
     private ViewStub mGutsStub;
     private boolean mHasExpandAction;
     private boolean mIsSystemChildExpanded;
+    private boolean mIsPinned;
     private OnClickListener mExpandClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
@@ -109,7 +109,6 @@
                     !mChildrenExpanded);
         }
     };
-    private boolean mInShade;
 
     public NotificationContentView getPrivateLayout() {
         return mPrivateLayout;
@@ -284,12 +283,18 @@
         return realActualHeight;
     }
 
-    public void setInShade(boolean inShade) {
-        mInShade = inShade;
+    /**
+     * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
+     * the notification will be rendered on top of the screen.
+     *
+     * @param pinned whether it is pinned
+     */
+    public void setPinned(boolean pinned) {
+        mIsPinned = pinned;
     }
 
-    public boolean isInShade() {
-        return mInShade;
+    public boolean isPinned() {
+        return mIsPinned;
     }
 
     public int getHeadsUpHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 1c53655..110b14c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -32,37 +32,34 @@
 import com.android.systemui.R;
 
 /**
- * A frame layout containing the actual payload of the notification, including the contracted and
- * expanded layout. This class is responsible for clipping the content and and switching between the
- * expanded and contracted view depending on its clipped size.
+ * A frame layout containing the actual payload of the notification, including the contracted,
+ * expanded and heads up layout. This class is responsible for clipping the content and and
+ * switching between the expanded, contracted and the heads up view depending on its clipped size.
  */
 public class NotificationContentView extends FrameLayout {
 
     private static final long ANIMATION_DURATION_LENGTH = 170;
-    private static final int CONTRACTED = 1;
-    private static final int EXPANDED = 2;
-    private static final int HEADSUP = 3;
+    private static final int VISIBLE_TYPE_CONTRACTED = 0;
+    private static final int VISIBLE_TYPE_EXPANDED = 1;
+    private static final int VISIBLE_TYPE_HEADSUP = 2;
 
     private final Rect mClipBounds = new Rect();
+    private final int mSmallHeight;
+    private final int mHeadsUpHeight;
+    private final Interpolator mLinearInterpolator = new LinearInterpolator();
 
     private View mContractedChild;
     private View mExpandedChild;
     private View mHeadsUpChild;
 
     private NotificationViewWrapper mContractedWrapper;
-
-    private final int mSmallHeight;
-    private final int mHeadsUpHeight;
     private int mClipTopAmount;
-
     private int mContentHeight;
-
-    private final Interpolator mLinearInterpolator = new LinearInterpolator();
-    private int mVisibleView = CONTRACTED;
-
+    private int mVisibleType = VISIBLE_TYPE_CONTRACTED;
     private boolean mDark;
     private final Paint mFadePaint = new Paint();
     private boolean mAnimate;
+    private boolean mIsHeadsUp;
     private ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener
             = new ViewTreeObserver.OnPreDrawListener() {
         @Override
@@ -72,7 +69,6 @@
             return true;
         }
     };
-    private boolean mIsHeadsUp;
 
     public NotificationContentView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -105,9 +101,9 @@
                 // An actual height is set
                 size = Math.min(maxSize, layoutParams.height);
             }
-            int spec = size == Integer.MAX_VALUE ?
-                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) :
-                    MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+            int spec = size == Integer.MAX_VALUE
+                    ? MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
+                    : MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
             mExpandedChild.measure(widthMeasureSpec, spec);
             maxChildHeight = Math.max(maxChildHeight, mExpandedChild.getMeasuredHeight());
         }
@@ -153,7 +149,7 @@
         mContractedChild = null;
         mExpandedChild = null;
         mHeadsUpChild = null;
-        mVisibleView = CONTRACTED;
+        mVisibleType = VISIBLE_TYPE_CONTRACTED;
         if (resetActualHeight) {
             mContentHeight = mSmallHeight;
         }
@@ -263,30 +259,32 @@
         if (mContractedChild == null) {
             return;
         }
-        int visibleView = calculateVisibleView();
-        if (visibleView != mVisibleView || force) {
-            if (animate && mExpandedChild != null) {
-                runSwitchAnimation(visibleView);
+        int visibleType = calculateVisibleType();
+        if (visibleType != mVisibleType || force) {
+            if (animate && (visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null)
+                    || (visibleType == VISIBLE_TYPE_HEADSUP && mHeadsUpChild != null)
+                    || visibleType == VISIBLE_TYPE_CONTRACTED) {
+                runSwitchAnimation(visibleType);
             } else {
-                updateViewVisibilities(visibleView);
+                updateViewVisibilities(visibleType);
             }
-            mVisibleView = visibleView;
+            mVisibleType = visibleType;
         }
     }
 
-    private void updateViewVisibilities(int visibleView) {
-        boolean contractedVisible = visibleView == CONTRACTED;
+    private void updateViewVisibilities(int visibleType) {
+        boolean contractedVisible = visibleType == VISIBLE_TYPE_CONTRACTED;
         mContractedChild.setVisibility(contractedVisible ? View.VISIBLE : View.INVISIBLE);
         mContractedChild.setAlpha(contractedVisible ? 1f : 0f);
         mContractedChild.setLayerType(LAYER_TYPE_NONE, null);
         if (mExpandedChild != null) {
-            boolean expandedVisible = visibleView == EXPANDED;
+            boolean expandedVisible = visibleType == VISIBLE_TYPE_EXPANDED;
             mExpandedChild.setVisibility(expandedVisible ? View.VISIBLE : View.INVISIBLE);
             mExpandedChild.setAlpha(expandedVisible ? 1f : 0f);
             mExpandedChild.setLayerType(LAYER_TYPE_NONE, null);
         }
         if (mHeadsUpChild != null) {
-            boolean headsUpVisible = visibleView == HEADSUP;
+            boolean headsUpVisible = visibleType == VISIBLE_TYPE_HEADSUP;
             mHeadsUpChild.setVisibility(headsUpVisible ? View.VISIBLE : View.INVISIBLE);
             mHeadsUpChild.setAlpha(headsUpVisible ? 1f : 0f);
             mHeadsUpChild.setLayerType(LAYER_TYPE_NONE, null);
@@ -294,9 +292,9 @@
         setLayerType(LAYER_TYPE_NONE, null);
     }
 
-    private void runSwitchAnimation(int visibleView) {
-        View shownView = getViewFromFlag(visibleView);
-        View hiddenView = getViewFromFlag(mVisibleView);
+    private void runSwitchAnimation(int visibleType) {
+        View shownView = getViewForVisibleType(visibleType);
+        View hiddenView = getViewForVisibleType(mVisibleType);
         shownView.setVisibility(View.VISIBLE);
         hiddenView.setVisibility(View.VISIBLE);
         shownView.setLayerType(LAYER_TYPE_HARDWARE, mFadePaint);
@@ -314,34 +312,42 @@
                 .withEndAction(new Runnable() {
                     @Override
                     public void run() {
-                        updateViewVisibilities(mVisibleView);
+                        updateViewVisibilities(mVisibleType);
                     }
                 });
     }
 
-    private View getViewFromFlag(int visibleView) {
-        switch (visibleView) {
-            case EXPANDED:
+    /**
+     * @param visibleType one of the static enum types in this view
+     * @return the corresponding view according to the given visible type
+     */
+    private View getViewForVisibleType(int visibleType) {
+        switch (visibleType) {
+            case VISIBLE_TYPE_EXPANDED:
                 return mExpandedChild;
-            case HEADSUP:
+            case VISIBLE_TYPE_HEADSUP:
                 return mHeadsUpChild;
+            default:
+                return mContractedChild;
         }
-        return mContractedChild;
     }
 
-    private int calculateVisibleView() {
+    /**
+     * @return one of the static enum types in this view, calculated form the current state
+     */
+    private int calculateVisibleType() {
         boolean noExpandedChild = mExpandedChild == null;
         if (mIsHeadsUp && mHeadsUpChild != null) {
             if (mContentHeight <= mHeadsUpChild.getHeight() || noExpandedChild) {
-                return HEADSUP;
+                return VISIBLE_TYPE_HEADSUP;
             } else {
-                return EXPANDED;
+                return VISIBLE_TYPE_EXPANDED;
             }
         } else {
             if (mContentHeight <= mSmallHeight || noExpandedChild) {
-                return CONTRACTED;
+                return VISIBLE_TYPE_CONTRACTED;
             } else {
-                return EXPANDED;
+                return VISIBLE_TYPE_EXPANDED;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 429889d..2a8b4ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -45,9 +45,6 @@
         public StatusBarNotification notification;
         public StatusBarIconView icon;
         public ExpandableNotificationRow row; // the outer expanded view
-        public View expanded; // the inflated RemoteViews
-        public View expandedPublic; // for insecure lockscreens
-        public View expandedBig;
         private boolean interruption;
         public boolean autoRedacted; // whether the redacted notification was generated by us
         public boolean legacy; // whether the notification has a legacy, dark background
@@ -58,14 +55,6 @@
             this.notification = n;
             this.icon = ic;
         }
-        public void setBigContentView(View bigContentView) {
-            this.expandedBig = bigContentView;
-            row.setExpandable(bigContentView != null);
-        }
-        public View getBigContentView() {
-            return expandedBig;
-        }
-        public View getPublicContentView() { return expandedPublic; }
 
         public void setInterruption() {
             interruption = true;
@@ -81,15 +70,28 @@
         public void reset() {
             // NOTE: Icon needs to be preserved for now.
             // We should fix this at some point.
-            expanded = null;
-            expandedPublic = null;
-            expandedBig = null;
             autoRedacted = false;
             legacy = false;
             if (row != null) {
                 row.reset();
             }
         }
+
+        public View getContentView() {
+            return row.getPrivateLayout().getContractedChild();
+        }
+
+        public View getExpandedContentView() {
+            return row.getPrivateLayout().getExpandedChild();
+        }
+
+        public View getHeadsUpContentView() {
+            return row.getPrivateLayout().getHeadsUpChild();
+        }
+
+        public View getPublicContentView() {
+            return row.getPublicLayout().getContractedChild();
+        }
     }
 
     private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
@@ -258,7 +260,7 @@
      */
     public boolean hasActiveClearableNotifications() {
         for (Entry e : mSortedAndFiltered) {
-            if (e.expanded != null) { // the view successfully inflated
+            if (e.getContentView() != null) { // the view successfully inflated
                 if (e.notification.isClearable()) {
                     return true;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 3997807..fe7bc97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -27,7 +27,7 @@
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 /**
- * A Helper class to handle touches on the heads-up views
+ * A helper class to handle touches on the heads-up views.
  */
 public class HeadsUpTouchHelper implements Gefingerpoken {
 
@@ -37,19 +37,30 @@
     private float mTouchSlop;
     private float mInitialTouchX;
     private float mInitialTouchY;
-    private boolean mMotionOnHeadsUpView;
+    private boolean mTouchingHeadsUpView;
     private boolean mTrackingHeadsUp;
     private boolean mCollapseSnoozes;
     private NotificationPanelView mPanel;
     private ExpandableNotificationRow mPickedChild;
 
+    public HeadsUpTouchHelper(HeadsUpManager headsUpManager,
+            NotificationStackScrollLayout stackScroller,
+            NotificationPanelView notificationPanelView) {
+        mHeadsUpManager = headsUpManager;
+        mStackScroller = stackScroller;
+        mPanel = notificationPanelView;
+        Context context = stackScroller.getContext();
+        final ViewConfiguration configuration = ViewConfiguration.get(context);
+        mTouchSlop = configuration.getScaledTouchSlop();
+    }
+
     public boolean isTrackingHeadsUp() {
         return mTrackingHeadsUp;
     }
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (!mMotionOnHeadsUpView && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
+        if (!mTouchingHeadsUpView && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
             return false;
         }
         int pointerIndex = event.findPointerIndex(mTrackingPointer);
@@ -65,10 +76,10 @@
                 mInitialTouchX = x;
                 setTrackingHeadsUp(false);
                 ExpandableView child = mStackScroller.getChildAtPosition(x, y);
-                mMotionOnHeadsUpView = false;
+                mTouchingHeadsUpView = false;
                 if (child instanceof ExpandableNotificationRow) {
                     mPickedChild = (ExpandableNotificationRow) child;
-                    mMotionOnHeadsUpView = mPickedChild.isHeadsUp() && !mPickedChild.isInShade();
+                    mTouchingHeadsUpView = mPickedChild.isHeadsUp() && mPickedChild.isPinned();
                 }
                 break;
             case MotionEvent.ACTION_POINTER_UP:
@@ -97,7 +108,8 @@
 
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
-                if (mPickedChild != null && mMotionOnHeadsUpView) {
+                if (mPickedChild != null && mTouchingHeadsUpView) {
+                    // We may swallow this click if the heads up just came in.
                     if (mHeadsUpManager.shouldSwallowClick(
                             mPickedChild.getStatusBarNotification().getKey())) {
                         endMotion();
@@ -141,20 +153,6 @@
     private void endMotion() {
         mTrackingPointer = -1;
         mPickedChild = null;
-        mMotionOnHeadsUpView = false;
-    }
-
-    public ExpandableView getPickedChild() {
-        return mPickedChild;
-    }
-
-    public void bind(HeadsUpManager headsUpManager, NotificationStackScrollLayout stackScroller,
-            NotificationPanelView notificationPanelView) {
-        mHeadsUpManager = headsUpManager;
-        mStackScroller = stackScroller;
-        mPanel = notificationPanelView;
-        Context context = stackScroller.getContext();
-        final ViewConfiguration configuration = ViewConfiguration.get(context);
-        mTouchSlop = configuration.getScaledTouchSlop();
+        mTouchingHeadsUpView = false;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index e5ef6ff..fabc1a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -86,7 +86,7 @@
 
     private KeyguardAffordanceView mCameraImageView;
     private KeyguardAffordanceView mPhoneImageView;
-    private KeyguardAffordanceView mLockIcon;
+    private LockIcon mLockIcon;
     private TextView mIndicationText;
     private ViewGroup mPreviewContainer;
 
@@ -102,11 +102,8 @@
     private AccessibilityController mAccessibilityController;
     private PhoneStatusBar mPhoneStatusBar;
 
-    private final TrustDrawable mTrustDrawable;
     private final Interpolator mLinearOutSlowInInterpolator;
-    private int mLastUnlockIconRes = 0;
     private boolean mPrewarmSent;
-    private boolean mTransientFpError;
 
     public KeyguardBottomAreaView(Context context) {
         this(context, null);
@@ -123,7 +120,6 @@
     public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mTrustDrawable = new TrustDrawable(mContext);
         mLinearOutSlowInInterpolator =
                 AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
     }
@@ -169,20 +165,19 @@
         mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
         mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
         mPhoneImageView = (KeyguardAffordanceView) findViewById(R.id.phone_button);
-        mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon);
+        mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
         mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
         watchForCameraPolicyChanges();
         updateCameraVisibility();
         updatePhoneVisibility();
         mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
         mUnlockMethodCache.addListener(this);
-        updateLockIcon();
+        mLockIcon.update();
         setClipChildren(false);
         setClipToPadding(false);
         mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
         inflatePreviews();
         mLockIcon.setOnClickListener(this);
-        mLockIcon.setBackground(mTrustDrawable);
         mLockIcon.setOnLongClickListener(this);
         mCameraImageView.setOnClickListener(this);
         mPhoneImageView.setOnClickListener(this);
@@ -222,6 +217,7 @@
 
     public void setAccessibilityController(AccessibilityController accessibilityController) {
         mAccessibilityController = accessibilityController;
+        mLockIcon.setAccessibilityController(accessibilityController);
         accessibilityController.addStateChangedCallback(this);
     }
 
@@ -233,9 +229,9 @@
     private Intent getCameraIntent() {
         KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
         boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
-                mLockPatternUtils.getCurrentUser());
-        return mLockPatternUtils.isSecure() && !currentUserHasTrust
-                ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
+                KeyguardUpdateMonitor.getCurrentUser());
+        boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
+        return (secure && !currentUserHasTrust) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
     }
 
     private void updateCameraVisibility() {
@@ -245,7 +241,7 @@
         }
         ResolveInfo resolved = mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
                 PackageManager.MATCH_DEFAULT_ONLY,
-                mLockPatternUtils.getCurrentUser());
+                KeyguardUpdateMonitor.getCurrentUser());
         boolean visible = !isCameraDisabledByDpm() && resolved != null
                 && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance);
         mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
@@ -294,21 +290,7 @@
         mPhoneImageView.setClickable(touchExplorationEnabled);
         mCameraImageView.setFocusable(accessibilityEnabled);
         mPhoneImageView.setFocusable(accessibilityEnabled);
-        updateLockIconClickability();
-    }
-
-    private void updateLockIconClickability() {
-        if (mAccessibilityController == null) {
-            return;
-        }
-        boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
-        boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
-                && !mAccessibilityController.isAccessibilityEnabled();
-        boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
-                && !clickToForceLock;
-        mLockIcon.setClickable(clickToForceLock || clickToUnlock);
-        mLockIcon.setLongClickable(longClickToForceLock);
-        mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
+        mLockIcon.update();
     }
 
     @Override
@@ -339,13 +321,13 @@
                 0 /* velocityDp - N/A */);
         mIndicationController.showTransientIndication(
                 R.string.keyguard_indication_trust_disabled);
-        mLockPatternUtils.requireCredentialEntry(mLockPatternUtils.getCurrentUser());
+        mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
     }
 
     public void prewarmCamera() {
         Intent intent = getCameraIntent();
         String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
-                mLockPatternUtils.getCurrentUser());
+                KeyguardUpdateMonitor.getCurrentUser());
         if (targetPackage != null) {
             Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_PREWARM);
             prewarm.setPackage(targetPackage);
@@ -361,7 +343,7 @@
         mPrewarmSent = false;
         Intent intent = getCameraIntent();
         String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
-                mLockPatternUtils.getCurrentUser());
+                KeyguardUpdateMonitor.getCurrentUser());
         if (targetPackage != null) {
             Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_COOLDOWN);
             prewarm.setPackage(targetPackage);
@@ -375,7 +357,7 @@
         mPrewarmSent = false;
         final Intent intent = getCameraIntent();
         boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
-                mContext, intent, mLockPatternUtils.getCurrentUser());
+                mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
         if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
             AsyncTask.execute(new Runnable() {
                 @Override
@@ -409,69 +391,12 @@
     @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
-        if (isShown()) {
-            mTrustDrawable.start();
-        } else {
-            mTrustDrawable.stop();
-        }
         if (changedView == this && visibility == VISIBLE) {
-            updateLockIcon();
+            mLockIcon.update();
             updateCameraVisibility();
         }
     }
 
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mTrustDrawable.stop();
-    }
-
-    private void updateLockIcon() {
-        boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
-        if (visible) {
-            mTrustDrawable.start();
-        } else {
-            mTrustDrawable.stop();
-        }
-        if (!visible) {
-            return;
-        }
-        // TODO: Real icon for facelock.
-        boolean isFingerprintIcon =
-                KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
-        boolean anyFingerprintIcon = isFingerprintIcon || mTransientFpError;
-        int iconRes = mTransientFpError ? R.drawable.ic_fingerprint_error
-                : isFingerprintIcon ? R.drawable.ic_fingerprint
-                : mUnlockMethodCache.isFaceUnlockRunning()
-                        ? com.android.internal.R.drawable.ic_account_circle
-                : mUnlockMethodCache.isCurrentlyInsecure() ? R.drawable.ic_lock_open_24dp
-                : R.drawable.ic_lock_24dp;
-
-        if (mLastUnlockIconRes != iconRes) {
-            Drawable icon = mContext.getDrawable(iconRes);
-            int iconHeight = getResources().getDimensionPixelSize(
-                    R.dimen.keyguard_affordance_icon_height);
-            int iconWidth = getResources().getDimensionPixelSize(
-                    R.dimen.keyguard_affordance_icon_width);
-            if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
-                    || icon.getIntrinsicWidth() != iconWidth)) {
-                icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
-            }
-            mLockIcon.setImageDrawable(icon);
-            mLockIcon.setPaddingRelative(0, 0, 0, anyFingerprintIcon
-                    ? getResources().getDimensionPixelSize(
-                            R.dimen.fingerprint_icon_additional_padding)
-                    : 0);
-            mLockIcon.setRestingAlpha(
-                    anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
-        }
-
-        // Hide trust circle when fingerprint is running.
-        boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !anyFingerprintIcon;
-        mTrustDrawable.setTrustManaged(trustManaged);
-        updateLockIconClickability();
-    }
-
     public KeyguardAffordanceView getPhoneView() {
         return mPhoneImageView;
     }
@@ -503,7 +428,7 @@
 
     @Override
     public void onUnlockMethodStateChanged() {
-        updateLockIcon();
+        mLockIcon.update();
         updateCameraVisibility();
     }
 
@@ -563,9 +488,8 @@
     private final Runnable mTransientFpErrorClearRunnable = new Runnable() {
         @Override
         public void run() {
-            mTransientFpError = false;
+            mLockIcon.setTransientFpError(false);
             mIndicationController.hideTransientIndication();
-            updateLockIcon();
         }
     };
 
@@ -578,17 +502,17 @@
 
         @Override
         public void onScreenTurnedOn() {
-            updateLockIcon();
+            mLockIcon.update();
         }
 
         @Override
         public void onScreenTurnedOff(int why) {
-            updateLockIcon();
+            mLockIcon.update();
         }
 
         @Override
         public void onKeyguardVisibilityChanged(boolean showing) {
-            updateLockIcon();
+            mLockIcon.update();
         }
 
         @Override
@@ -597,24 +521,21 @@
 
         @Override
         public void onFingerprintRunningStateChanged(boolean running) {
-            updateLockIcon();
+            mLockIcon.update();
         }
 
         @Override
         public void onFingerprintHelp(int msgId, String helpString) {
-            mTransientFpError = true;
+            mLockIcon.setTransientFpError(true);
             mIndicationController.showTransientIndication(helpString,
                     getResources().getColor(R.color.system_warning_color, null));
             removeCallbacks(mTransientFpErrorClearRunnable);
             postDelayed(mTransientFpErrorClearRunnable, TRANSIENT_FP_ERROR_TIMEOUT);
-            updateLockIcon();
         }
 
         @Override
         public void onFingerprintError(int msgId, String errString) {
             // TODO: Go to bouncer if this is "too many attempts" (lockout) error.
-            Log.i(TAG, "FP Error: " + errString);
-            updateLockIcon();
         }
     };
 
@@ -622,29 +543,4 @@
             KeyguardIndicationController keyguardIndicationController) {
         mIndicationController = keyguardIndicationController;
     }
-
-    /**
-     * A wrapper around another Drawable that overrides the intrinsic size.
-     */
-    private static class IntrinsicSizeDrawable extends InsetDrawable {
-
-        private final int mIntrinsicWidth;
-        private final int mIntrinsicHeight;
-
-        public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
-            super(drawable, 0);
-            mIntrinsicWidth = intrinsicWidth;
-            mIntrinsicHeight = intrinsicHeight;
-        }
-
-        @Override
-        public int getIntrinsicWidth() {
-            return mIntrinsicWidth;
-        }
-
-        @Override
-        public int getIntrinsicHeight() {
-            return mIntrinsicHeight;
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
new file mode 100644
index 0000000..66f3232
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.policy.AccessibilityController;
+
+/**
+ * Manages the different states and animations of the unlock icon.
+ */
+public class LockIcon extends KeyguardAffordanceView {
+
+
+    private static final int STATE_LOCKED = 0;
+    private static final int STATE_LOCK_OPEN = 1;
+    private static final int STATE_FACE_UNLOCK = 2;
+    private static final int STATE_FINGERPRINT = 3;
+    private static final int STATE_FINGERPRINT_ERROR = 4;
+
+    private int mLastState = 0;
+    private boolean mTransientFpError;
+    private final TrustDrawable mTrustDrawable;
+    private final UnlockMethodCache mUnlockMethodCache;
+    private AccessibilityController mAccessibilityController;
+
+    public LockIcon(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mTrustDrawable = new TrustDrawable(context);
+        setBackground(mTrustDrawable);
+        mUnlockMethodCache = UnlockMethodCache.getInstance(context);
+    }
+
+    @Override
+    protected void onVisibilityChanged(View changedView, int visibility) {
+        super.onVisibilityChanged(changedView, visibility);
+        if (isShown()) {
+            mTrustDrawable.start();
+        } else {
+            mTrustDrawable.stop();
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mTrustDrawable.stop();
+    }
+
+    public void setTransientFpError(boolean transientFpError) {
+        mTransientFpError = transientFpError;
+        update();
+    }
+
+    public void update() {
+        boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+        if (visible) {
+            mTrustDrawable.start();
+        } else {
+            mTrustDrawable.stop();
+        }
+        if (!visible) {
+            return;
+        }
+        // TODO: Real icon for facelock.
+        int state = getState();
+        boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
+        if (state != mLastState) {
+            int iconRes = getAnimationResForTransition(mLastState, state);
+            if (iconRes == -1) {
+                iconRes = getIconForState(state);
+            }
+            Drawable icon = mContext.getDrawable(iconRes);
+            AnimatedVectorDrawable animation = null;
+            if (icon instanceof AnimatedVectorDrawable) {
+                animation = (AnimatedVectorDrawable) icon;
+            }
+            int iconHeight = getResources().getDimensionPixelSize(
+                    R.dimen.keyguard_affordance_icon_height);
+            int iconWidth = getResources().getDimensionPixelSize(
+                    R.dimen.keyguard_affordance_icon_width);
+            if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
+                    || icon.getIntrinsicWidth() != iconWidth)) {
+                icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
+            }
+            setPaddingRelative(0, 0, 0, anyFingerprintIcon
+                    ? getResources().getDimensionPixelSize(
+                    R.dimen.fingerprint_icon_additional_padding)
+                    : 0);
+            setRestingAlpha(
+                    anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
+            setImageDrawable(icon);
+            if (animation != null) {
+                animation.start();
+            }
+        }
+
+        // Hide trust circle when fingerprint is running.
+        boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !anyFingerprintIcon;
+        mTrustDrawable.setTrustManaged(trustManaged);
+        mLastState = state;
+        updateClickability();
+    }
+
+    private void updateClickability() {
+        if (mAccessibilityController == null) {
+            return;
+        }
+        boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
+        boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
+                && !mAccessibilityController.isAccessibilityEnabled();
+        boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
+                && !clickToForceLock;
+        setClickable(clickToForceLock || clickToUnlock);
+        setLongClickable(longClickToForceLock);
+        setFocusable(mAccessibilityController.isAccessibilityEnabled());
+    }
+
+    public void setAccessibilityController(AccessibilityController accessibilityController) {
+        mAccessibilityController = accessibilityController;
+    }
+
+    private int getIconForState(int state) {
+        switch (state) {
+            case STATE_LOCKED:
+                return R.drawable.ic_lock_24dp;
+            case STATE_LOCK_OPEN:
+                return R.drawable.ic_lock_open_24dp;
+            case STATE_FACE_UNLOCK:
+                return com.android.internal.R.drawable.ic_account_circle;
+            case STATE_FINGERPRINT:
+                return R.drawable.ic_fingerprint;
+            case STATE_FINGERPRINT_ERROR:
+                return R.drawable.ic_fingerprint_error;
+            default:
+                throw new IllegalArgumentException();
+        }
+    }
+
+    private int getAnimationResForTransition(int oldState, int newState) {
+        if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
+            return R.drawable.lockscreen_fingerprint_error_state_animation;
+        } else {
+            return -1;
+        }
+    }
+
+    private int getState() {
+        boolean fingerprintRunning =
+                KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
+        if (mTransientFpError) {
+            return STATE_FINGERPRINT_ERROR;
+        } else if (fingerprintRunning) {
+            return STATE_FINGERPRINT;
+        } else if (mUnlockMethodCache.isFaceUnlockRunning()) {
+            return STATE_FACE_UNLOCK;
+        } else if (mUnlockMethodCache.isCurrentlyInsecure()) {
+            return STATE_LOCK_OPEN;
+        } else {
+            return STATE_LOCKED;
+        }
+    }
+
+    /**
+     * A wrapper around another Drawable that overrides the intrinsic size.
+     */
+    private static class IntrinsicSizeDrawable extends InsetDrawable {
+
+        private final int mIntrinsicWidth;
+        private final int mIntrinsicHeight;
+
+        public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
+            super(drawable, 0);
+            mIntrinsicWidth = intrinsicWidth;
+            mIntrinsicHeight = intrinsicHeight;
+        }
+
+        @Override
+        public int getIntrinsicWidth() {
+            return mIntrinsicWidth;
+        }
+
+        @Override
+        public int getIntrinsicHeight() {
+            return mIntrinsicHeight;
+        }
+    }
+}
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 b87c25b..8914fb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -182,11 +182,11 @@
 
     private float mKeyguardStatusBarAnimateAlpha = 1f;
     private int mOldLayoutDirection;
-    private HeadsUpTouchHelper mHeadsUpTouchHelper = new HeadsUpTouchHelper();
-    private boolean mPinnedHeadsUpExist;
-    private boolean mExpansionIsFromHeadsUp;
-    private int mBottomBarHeight;
+    private HeadsUpTouchHelper mHeadsUpTouchHelper;
+    private boolean mIsExpansionFromHeadsUp;
+    private int mNavigationBarBottomHeight;
     private boolean mExpandingFromHeadsUp;
+    private boolean mCollapsedOnDown;
     private int mPositionMinSideMargin;
     private int mLastOrientation = -1;
 
@@ -534,17 +534,16 @@
     }
 
     @Override
-    public boolean
-    onInterceptTouchEvent(MotionEvent event) {
+    public boolean onInterceptTouchEvent(MotionEvent event) {
         if (mBlockTouches) {
             return false;
         }
         initDownStates(event);
         if (mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
-            mExpansionIsFromHeadsUp = true;
+            mIsExpansionFromHeadsUp = true;
             return true;
         }
-        if (!isShadeCollapsed() && onQsIntercept(event)) {
+        if (!isFullyCollapsed() && onQsIntercept(event)) {
             return true;
         }
         return super.onInterceptTouchEvent(event);
@@ -641,6 +640,7 @@
             mOnlyAffordanceInThisMotion = false;
             mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
             mDozingOnDown = isDozing();
+            mCollapsedOnDown = isFullyCollapsed();
         }
     }
 
@@ -695,7 +695,7 @@
             return true;
         }
         mHeadsUpTouchHelper.onTouchEvent(event);
-        if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQSTouch(event)) {
+        if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
             return true;
         }
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
@@ -705,7 +705,7 @@
         return true;
     }
 
-    private boolean handleQSTouch(MotionEvent event) {
+    private boolean handleQsTouch(MotionEvent event) {
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
                 && mStatusBar.getBarState() != StatusBarState.KEYGUARD && !mQsExpanded
                 && mQsExpansionEnabled) {
@@ -718,7 +718,7 @@
             mInitialTouchY = event.getX();
             mInitialTouchX = event.getY();
         }
-        if (!isShadeCollapsed()) {
+        if (!isFullyCollapsed()) {
             handleQsDown(event);
         }
         if (!mQsExpandImmediate && mQsTracking) {
@@ -731,7 +731,7 @@
                 || event.getActionMasked() == MotionEvent.ACTION_UP) {
             mConflictingQsExpansionGesture = false;
         }
-        if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isShadeCollapsed()
+        if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()
                 && mQsExpansionEnabled) {
             mTwoFingerQsExpandPossible = true;
         }
@@ -1191,8 +1191,8 @@
         updateEmptyShadeView();
         mQsNavbarScrim.setVisibility(mStatusBarState == StatusBarState.SHADE && mQsExpanded
                 && !mStackScrollerOverscrolling && mQsScrimEnabled
-                ? View.VISIBLE
-                : View.INVISIBLE);
+                        ? View.VISIBLE
+                        : View.INVISIBLE);
         if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
             mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
         }
@@ -1386,7 +1386,7 @@
      * @return Whether we should intercept a gesture to open Quick Settings.
      */
     private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
-        if (!mQsExpansionEnabled) {
+        if (!mQsExpansionEnabled || mCollapsedOnDown) {
             return false;
         }
         View header = mKeyguardShowing ? mKeyguardStatusBar : mHeader;
@@ -1461,8 +1461,8 @@
         updateHeader();
         updateUnlockIcon();
         updateNotificationTranslucency();
-        mHeadsUpManager.setIsExpanded(!isShadeCollapsed());
-        mNotificationStackScroller.setShadeExpanded(!isShadeCollapsed());
+        mHeadsUpManager.setIsExpanded(!isFullyCollapsed());
+        mNotificationStackScroller.setShadeExpanded(!isFullyCollapsed());
         if (DEBUG) {
             invalidate();
         }
@@ -1535,21 +1535,19 @@
         float alpha;
         if (mExpandingFromHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) {
             alpha = 1f;
-            if (mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
-                mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
-            }
         } else {
             alpha = (getNotificationsTopY() + mNotificationStackScroller.getItemHeight())
                     / (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize()
                     - mNotificationStackScroller.getCollapseSecondCardPadding());
             alpha = Math.max(0, Math.min(alpha, 1));
             alpha = (float) Math.pow(alpha, 0.75);
-            if (alpha != 1f && mNotificationStackScroller.getLayerType() != LAYER_TYPE_HARDWARE) {
-                mNotificationStackScroller.setLayerType(LAYER_TYPE_HARDWARE, null);
-            } else if (alpha == 1f
-                    && mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
-                mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
-            }
+        }
+
+        if (alpha != 1f && mNotificationStackScroller.getLayerType() != LAYER_TYPE_HARDWARE) {
+            mNotificationStackScroller.setLayerType(LAYER_TYPE_HARDWARE, null);
+        } else if (alpha == 1f
+                && mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
+            mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
         }
         mNotificationStackScroller.setAlpha(alpha);
     }
@@ -1615,7 +1613,7 @@
         }
         float stackTranslation = mNotificationStackScroller.getStackTranslation();
         float translation = stackTranslation / HEADER_RUBBERBAND_FACTOR;
-        if (mHeadsUpManager.hasPinnedHeadsUp() || mExpansionIsFromHeadsUp) {
+        if (mHeadsUpManager.hasPinnedHeadsUp() || mIsExpansionFromHeadsUp) {
             translation = mNotificationStackScroller.getTopPadding() + stackTranslation
                     - mNotificationTopPadding - mQsMinExpansionHeight;
         }
@@ -1683,16 +1681,16 @@
         mHeadsUpManager.onExpandingFinished();
         mIsExpanding = false;
         mScrollYOverride = -1;
-        if (isShadeCollapsed()) {
+        if (isFullyCollapsed()) {
             setListening(false);
         } else {
             setListening(true);
         }
         mQsExpandImmediate = false;
         mTwoFingerQsExpandPossible = false;
-        mExpansionIsFromHeadsUp = false;
-        mNotificationStackScroller.setTrackingHeadsUp(mHeadsUpTouchHelper.isTrackingHeadsUp());
-        mExpandingFromHeadsUp = mHeadsUpTouchHelper.isTrackingHeadsUp();
+        mIsExpansionFromHeadsUp = false;
+        mNotificationStackScroller.setTrackingHeadsUp(false);
+        mExpandingFromHeadsUp = false;
     }
 
     private void setListening(boolean listening) {
@@ -1793,13 +1791,13 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        mBottomBarHeight = insets.getSystemWindowInsetBottom();
+        mNavigationBarBottomHeight = insets.getSystemWindowInsetBottom();
         updateMaxHeadsUpTranslation();
         return insets;
     }
 
     private void updateMaxHeadsUpTranslation() {
-        mNotificationStackScroller.setHeadsUpBoundaries(getHeight(), mBottomBarHeight);
+        mNotificationStackScroller.setHeadsUpBoundaries(getHeight(), mNavigationBarBottomHeight);
     }
 
     @Override
@@ -2160,48 +2158,43 @@
     }
 
     @Override
-    public void OnPinnedHeadsUpExistChanged(final boolean exist, boolean changeImmediatly) {
-        if (exist != mPinnedHeadsUpExist) {
-            mPinnedHeadsUpExist = exist;
-            if (exist) {
-                mHeadsUpExistenceChangedRunnable.run();
-                updateNotificationTranslucency();
-            } else {
-                mNotificationStackScroller.performOnAnimationFinished(
-                        mHeadsUpExistenceChangedRunnable);
-            }
+    public void onPinnedModeChanged(final boolean inPinnedMode) {
+        if (inPinnedMode) {
+            mHeadsUpExistenceChangedRunnable.run();
+            updateNotificationTranslucency();
+        } else {
+            mNotificationStackScroller.runAfterAnimationFinished(
+                    mHeadsUpExistenceChangedRunnable);
         }
     }
 
     @Override
-    public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
-        if (isHeadsUp) {
-            mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true);
-        }
+    public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+        mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true);
     }
 
     @Override
-    public void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
+    public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+    }
+
+    @Override
+    public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
         mNotificationStackScroller.generateHeadsUpAnimation(entry.row, isHeadsUp);
     }
 
     @Override
-    protected boolean isShadeCollapsed() {
-        return mExpandedHeight == 0;
-    }
-
-    @Override
     public void setHeadsUpManager(HeadsUpManager headsUpManager) {
         super.setHeadsUpManager(headsUpManager);
-        mHeadsUpTouchHelper.bind(headsUpManager, mNotificationStackScroller, this);
+        mHeadsUpTouchHelper = new HeadsUpTouchHelper(headsUpManager, mNotificationStackScroller,
+                this);
     }
 
     public void setTrackingHeadsUp(boolean tracking) {
         if (tracking) {
-            // otherwise we update the state when the expansion is finished
             mNotificationStackScroller.setTrackingHeadsUp(true);
             mExpandingFromHeadsUp = true;
         }
+        // otherwise we update the state when the expansion is finished
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 4452dd7c..85f312c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -46,13 +46,13 @@
 public abstract class PanelView extends FrameLayout {
     public static final boolean DEBUG = PanelBar.DEBUG;
     public static final String TAG = PanelView.class.getSimpleName();
-    protected HeadsUpManager mHeadsUpManager;
-
     private final void logf(String fmt, Object... args) {
         Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
     }
 
     protected PhoneStatusBar mStatusBar;
+    protected HeadsUpManager mHeadsUpManager;
+
     private float mPeekHeight;
     private float mHintDistance;
     private int mEdgeTapAreaWidth;
@@ -242,15 +242,15 @@
         final float y = event.getY(pointerIndex);
 
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            mGestureWaitForTouchSlop = isShadeCollapsed() || hasConflictingGestures();
-            mIgnoreXTouchSlop = isShadeCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
+            mGestureWaitForTouchSlop = isFullyCollapsed() || hasConflictingGestures();
+            mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
         }
 
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN:
                 startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
                 mJustPeeked = false;
-                mPanelClosedOnDown = isShadeCollapsed();
+                mPanelClosedOnDown = isFullyCollapsed();
                 mHasLayoutedSinceDown = false;
                 mUpdateFlingOnLayout = false;
                 mMotionAborted = false;
@@ -268,7 +268,7 @@
                             || mPeekPending || mPeekAnimator != null;
                     onTrackingStarted();
                 }
-                if (isShadeCollapsed()) {
+                if (isFullyCollapsed()) {
                     schedulePeek();
                 }
                 break;
@@ -472,7 +472,7 @@
                 mTouchSlopExceeded = false;
                 mJustPeeked = false;
                 mMotionAborted = false;
-                mPanelClosedOnDown = isShadeCollapsed();
+                mPanelClosedOnDown = isFullyCollapsed();
                 mHasLayoutedSinceDown = false;
                 mUpdateFlingOnLayout = false;
                 mTouchAboveFalsingThreshold = false;
@@ -707,7 +707,7 @@
         // If the user isn't actively poking us, let's update the height
         if ((!mTracking || isTrackingBlocked())
                 && mHeightAnimator == null
-                && !isShadeCollapsed()
+                && !isFullyCollapsed()
                 && currentMaxPanelHeight != mExpandedHeight
                 && !mPeekPending
                 && mPeekAnimator == null
@@ -1057,8 +1057,6 @@
      */
     protected abstract int getClearAllHeight();
 
-    protected abstract boolean isShadeCollapsed();
-
     public void setHeadsUpManager(HeadsUpManager headsUpManager) {
         mHeadsUpManager = headsUpManager;
     }
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 12c5589..bf27e84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -305,7 +305,8 @@
     ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
 
     // for disabling the status bar
-    int mDisabled = 0;
+    int mDisabled1 = 0;
+    int mDisabled2 = 0;
 
     // tracking calls to View.setSystemUiVisibility()
     int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
@@ -427,7 +428,8 @@
         }
     };
 
-    private int mDisabledUnmodified;
+    private int mDisabledUnmodified1;
+    private int mDisabledUnmodified2;
 
     /** Keys of notifications currently visible to the user. */
     private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>();
@@ -637,7 +639,7 @@
                 mNavigationBarView =
                     (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
 
-                mNavigationBarView.setDisabledFlags(mDisabled);
+                mNavigationBarView.setDisabledFlags(mDisabled1);
                 mNavigationBarView.setBar(this);
                 mNavigationBarView.setOnVerticalChangedListener(
                         new NavigationBarView.OnVerticalChangedListener() {
@@ -1150,11 +1152,11 @@
 
     @Override
     public void removeNotification(String key, RankingMap ranking) {
-        boolean defferRemoval = false;
+        boolean deferRemoval = false;
         if (mHeadsUpManager.isHeadsUp(key)) {
-            defferRemoval = !mHeadsUpManager.removeNotification(key);
+            deferRemoval = !mHeadsUpManager.removeNotification(key);
         }
-        if (defferRemoval) {
+        if (deferRemoval) {
             mLatestRankingMap = ranking;
             mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
             return;
@@ -1291,13 +1293,20 @@
         updateClearAll();
         updateEmptyShadeView();
 
-        // Disable QS if device not provisioned.
-        // If the user switcher is simple then disable QS during setup because
-        // the user intends to use the lock screen user switcher, QS in not needed.
+        updateQsExpansionEnabled();
+        mShadeUpdates.check();
+    }
+
+    /**
+     * Disable QS if device not provisioned.
+     * If the user switcher is simple then disable QS during setup because
+     * the user intends to use the lock screen user switcher, QS in not needed.
+     */
+    private void updateQsExpansionEnabled() {
         mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
                 && (mUserSetup || mUserSwitcherController == null
-                        || !mUserSwitcherController.isSimpleUserSwitcher()));
-        mShadeUpdates.check();
+                        || !mUserSwitcherController.isSimpleUserSwitcher())
+                && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0));
     }
 
     private void updateNotificationShadeForChildren() {
@@ -1691,86 +1700,100 @@
     /**
      * State is one or more of the DISABLE constants from StatusBarManager.
      */
-    public void disable(int state, boolean animate) {
-        mDisabledUnmodified = state;
-        state = adjustDisableFlags(state);
-        final int old = mDisabled;
-        final int diff = state ^ old;
-        mDisabled = state;
+    public void disable(int state1, int state2, boolean animate) {
+        mDisabledUnmodified1 = state1;
+        mDisabledUnmodified2 = state2;
+        state1 = adjustDisableFlags(state1);
+        final int old1 = mDisabled1;
+        final int diff1 = state1 ^ old1;
+        mDisabled1 = state1;
+
+        final int old2 = mDisabled2;
+        final int diff2 = state2 ^ old2;
+        mDisabled2 = state2;
 
         if (DEBUG) {
-            Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
-                old, state, diff));
+            Log.d(TAG, String.format("disable1: 0x%08x -> 0x%08x (diff1: 0x%08x)",
+                old1, state1, diff1));
+            Log.d(TAG, String.format("disable2: 0x%08x -> 0x%08x (diff2: 0x%08x)",
+                old2, state2, diff2));
         }
 
         StringBuilder flagdbg = new StringBuilder();
         flagdbg.append("disable: < ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
+        flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
+        flagdbg.append(((diff1  & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
+        flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
+                : "quick_settings");
+        flagdbg.append(((diff2  & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
         flagdbg.append(">");
         Log.d(TAG, flagdbg.toString());
 
-        if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
-            if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
+        if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
+            if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
                 mIconController.hideSystemIconArea(animate);
             } else {
                 mIconController.showSystemIconArea(animate);
             }
         }
 
-        if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
-            boolean visible = (state & StatusBarManager.DISABLE_CLOCK) == 0;
+        if ((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) {
+            boolean visible = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
             mIconController.setClockVisibility(visible);
         }
-        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
-            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
+        if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
+            if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
                 animateCollapsePanels();
             }
         }
 
-        if ((diff & (StatusBarManager.DISABLE_HOME
+        if ((diff1 & (StatusBarManager.DISABLE_HOME
                         | StatusBarManager.DISABLE_RECENT
                         | StatusBarManager.DISABLE_BACK
                         | StatusBarManager.DISABLE_SEARCH)) != 0) {
             // the nav bar will take care of these
-            if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
+            if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
 
-            if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
+            if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
                 // close recents if it's visible
                 mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
                 mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
             }
         }
 
-        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
-            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
+        if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
+            if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
                 mIconController.hideNotificationIconArea(animate);
             } else {
                 mIconController.showNotificationIconArea(animate);
             }
         }
 
-        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
+        if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
             mDisableNotificationAlerts =
-                    (state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+                    (state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
             mHeadsUpObserver.onChange(true);
         }
+
+        if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
+            updateQsExpansionEnabled();
+        }
     }
 
     @Override
@@ -1829,8 +1852,8 @@
     }
 
     @Override
-    public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
-        if (exist) {
+    public void onPinnedModeChanged(boolean inPinnedMode) {
+        if (inPinnedMode) {
             mStatusBarWindowManager.setHeadsUpShowing(true);
         } else {
             Runnable endRunnable = new Runnable() {
@@ -1841,20 +1864,24 @@
                     }
                 }
             };
-            if (changeImmediatly) {
+            if (!mNotificationPanel.isFullyCollapsed()) {
                 endRunnable.run();
             } else {
-                mStackScroller.performOnAnimationFinished(endRunnable);
+                mStackScroller.runAfterAnimationFinished(endRunnable);
             }
         }
     }
 
     @Override
-    public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
+    public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
     }
 
     @Override
-    public void OnHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
+    public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+    }
+
+    @Override
+    public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
         if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
             removeNotification(entry.key, mLatestRankingMap);
             mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
@@ -1871,10 +1898,11 @@
             boolean alertAgain) {
         final boolean wasHeadsUp = isHeadsUp(key);
         if (wasHeadsUp) {
-            mHeadsUpManager.updateNotification(entry, alertAgain);
             if (!shouldInterrupt) {
                 // We don't want this to be interrupting anymore, lets remove it
                 mHeadsUpManager.removeNotification(key);
+            } else {
+                mHeadsUpManager.updateNotification(entry, alertAgain);
             }
         } else if (shouldInterrupt && alertAgain) {
             // This notification was updated to be a heads-up, show it!
@@ -1920,7 +1948,7 @@
     }
 
     @Override
-    public void escalateHeadsUp() {
+    public void maybeEscalateHeadsUp() {
         TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries();
         for (HeadsUpManager.HeadsUpEntry entry : entries) {
             final StatusBarNotification sbn = entry.entry.notification;
@@ -1941,7 +1969,7 @@
     }
 
     boolean panelsEnabled() {
-        return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
+        return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0;
     }
 
     void makeExpandedVisible(boolean force) {
@@ -1961,7 +1989,7 @@
 
         visibilityChanged(true);
         mWaitingForKeyguardExit = false;
-        disable(mDisabledUnmodified, !force /* animate */);
+        disable(mDisabledUnmodified1, mDisabledUnmodified2, !force /* animate */);
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
     }
 
@@ -2094,7 +2122,7 @@
         runPostCollapseRunnables();
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
         showBouncer();
-        disable(mDisabledUnmodified, true /* animate */);
+        disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
 
         // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
         // the bouncer appear animation.
@@ -2107,20 +2135,21 @@
         if (DEBUG_GESTURES) {
             if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
                 EventLog.writeEvent(EventLogTags.SYSUI_STATUSBAR_TOUCH,
-                        event.getActionMasked(), (int) event.getX(), (int) event.getY(), mDisabled);
+                        event.getActionMasked(), (int) event.getX(), (int) event.getY(),
+                        mDisabled1, mDisabled2);
             }
 
         }
 
         if (SPEW) {
-            Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
-                + mDisabled + " mTracking=" + mTracking);
+            Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
+                + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
         } else if (CHATTY) {
             if (event.getAction() != MotionEvent.ACTION_MOVE) {
                 Log.d(TAG, String.format(
-                            "panel: %s at (%f, %f) mDisabled=0x%08x",
+                            "panel: %s at (%f, %f) mDisabled1=0x%08x mDisabled2=0x%08x",
                             MotionEvent.actionToString(event.getAction()),
-                            event.getRawX(), event.getRawY(), mDisabled));
+                            event.getRawX(), event.getRawY(), mDisabled1, mDisabled2));
             }
         }
 
@@ -2842,6 +2871,7 @@
         } catch (RemoteException e) {
             // Ignore.
         }
+        setNotificationsShown(newlyVisibleAr);
     }
 
     // State logging
@@ -2921,7 +2951,7 @@
     public boolean shouldDisableNavbarGestures() {
         return !isDeviceProvisioned()
                 || mExpandedVisible
-                || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
+                || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
     public void postStartSettingsActivity(final Intent intent, int delay) {
@@ -3235,7 +3265,7 @@
                 startTime + fadeoutDuration
                         - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION,
                 StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION);
-        disable(mDisabledUnmodified, true /* animate */);
+        disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
     }
 
     public boolean isKeyguardFadingAway() {
@@ -3547,7 +3577,7 @@
     @Override
     public void setBouncerShowing(boolean bouncerShowing) {
         super.setBouncerShowing(bouncerShowing);
-        disable(mDisabledUnmodified, true /* animate */);
+        disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */);
     }
 
     public void onScreenTurnedOff() {
@@ -3591,7 +3621,7 @@
                 if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
                     activityManager.stopLockTaskModeOnCurrent();
                     // When exiting refresh disabled flags.
-                    mNavigationBarView.setDisabledFlags(mDisabled, true);
+                    mNavigationBarView.setDisabledFlags(mDisabled1, true);
                 } else if ((v.getId() == R.id.back)
                         && !mNavigationBarView.getRecentsButton().isPressed()) {
                     // If we aren't pressing recents right now then they presses
@@ -3608,7 +3638,7 @@
                     // should stop lock task.
                     activityManager.stopLockTaskModeOnCurrent();
                     // When exiting refresh disabled flags.
-                    mNavigationBarView.setDisabledFlags(mDisabled, true);
+                    mNavigationBarView.setDisabledFlags(mDisabled1, true);
                 }
             }
             if (sendBackLongPress) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index fb42ba1d..0e8e844 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -224,14 +224,14 @@
         } else if (mZen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
             zenVisible = true;
             zenIconId = R.drawable.stat_sys_zen_none;
-            zenDescription = mContext.getString(R.string.zen_no_interruptions);
+            zenDescription = mContext.getString(R.string.interruption_level_none);
         } else if (mZen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
             zenVisible = true;
             zenIconId = R.drawable.stat_sys_zen_important;
-            zenDescription = mContext.getString(R.string.zen_important_interruptions);
+            zenDescription = mContext.getString(R.string.interruption_level_priority);
         }
 
-        if (DndTile.isVisible(mContext)
+        if (DndTile.isVisible(mContext) && !DndTile.isCombinedIcon(mContext)
                 && audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
             volumeVisible = true;
             volumeIconId = R.drawable.stat_sys_ringer_silent;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index e701783..ae98e76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -80,7 +80,7 @@
     private float mCurrentInFrontAlpha;
     private float mCurrentBehindAlpha;
     private float mCurrentHeadsUpAlpha = 1;
-    private int mAmountOfPinnedHeadsUps;
+    private int mPinnedHeadsUpCount;
     private float mTopHeadsUpDragAmount;
     private View mDraggedHeadsUpView;
 
@@ -347,25 +347,27 @@
     }
 
     @Override
-    public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
+    public void onPinnedModeChanged(boolean inPinnedMode) {
     }
 
     @Override
-    public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
-        if (isHeadsUp) {
-            mAmountOfPinnedHeadsUps++;
-        } else {
-            mAmountOfPinnedHeadsUps--;
-            if (headsUp == mDraggedHeadsUpView) {
-                mDraggedHeadsUpView = null;
-                mTopHeadsUpDragAmount = 0.0f;
-            }
+    public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+        mPinnedHeadsUpCount++;
+        updateHeadsUpScrim(true);
+    }
+
+    @Override
+    public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+        mPinnedHeadsUpCount--;
+        if (headsUp == mDraggedHeadsUpView) {
+            mDraggedHeadsUpView = null;
+            mTopHeadsUpDragAmount = 0.0f;
         }
         updateHeadsUpScrim(true);
     }
 
     @Override
-    public void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
+    public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
     }
 
     private void updateHeadsUpScrim(boolean animate) {
@@ -374,12 +376,10 @@
                 TAG_KEY_ANIM);
         float animEndValue = -1;
         if (previousAnimator != null) {
-            if ((animate || alpha == mCurrentHeadsUpAlpha)) {
-                // lets cancel any running animators
+            if (animate || alpha == mCurrentHeadsUpAlpha) {
                 previousAnimator.cancel();
             }
-            animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
-                    TAG_HUN_START_ALPHA);
+            animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim, TAG_HUN_START_ALPHA);
         }
         if (alpha != mCurrentHeadsUpAlpha && alpha != animEndValue) {
             if (animate) {
@@ -390,7 +390,7 @@
                 if (previousAnimator != null) {
                     float previousStartValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
                             TAG_HUN_START_ALPHA);
-                   float previousEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
+                    float previousEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
                            TAG_HUN_END_ALPHA);
                     // we need to increase all animation keyframes of the previous animator by the
                     // relative change to the end value
@@ -410,6 +410,13 @@
         }
     }
 
+    /**
+     * Set the amount the current top heads up view is dragged. The range is from 0 to 1 and 0 means
+     * the heads up is in its resting space and 1 means it's fully dragged out.
+     *
+     * @param draggedHeadsUpView the dragged view
+     * @param topHeadsUpDragAmount how far is it dragged
+     */
     public void setTopHeadsUpDragAmount(View draggedHeadsUpView, float topHeadsUpDragAmount) {
         mTopHeadsUpDragAmount = topHeadsUpDragAmount;
         mDraggedHeadsUpView = draggedHeadsUpView;
@@ -417,9 +424,9 @@
     }
 
     private float calculateHeadsUpAlpha() {
-        if (mAmountOfPinnedHeadsUps >= 2) {
+        if (mPinnedHeadsUpCount >= 2) {
             return 1.0f;
-        } else if (mAmountOfPinnedHeadsUps == 0) {
+        } else if (mPinnedHeadsUpCount == 0) {
             return 0.0f;
         } else {
             return 1.0f - mTopHeadsUpDragAmount;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
index 4a43c47..45c8938 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
 
 import java.util.HashMap;
 import java.util.List;
@@ -228,7 +229,7 @@
 
         // Get the list of applications that can handle the intent.
         final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
-                intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+                intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser());
         if (appList.size() == 0) {
             if (DEBUG) Log.d(TAG, "No targets found for secure camera intent");
             return false;
@@ -237,7 +238,7 @@
         // Get the application that the intent resolves to.
         ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
                 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
-                mLockPatternUtils.getCurrentUser());
+                KeyguardUpdateMonitor.getCurrentUser());
 
         if (resolved == null || resolved.activityInfo == null) {
             return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 65cd268..66d71f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -80,8 +80,8 @@
     }
 
     private void update(boolean updateAlways) {
-        int user = mLockPatternUtils.getCurrentUser();
-        boolean secure = mLockPatternUtils.isSecure();
+        int user = KeyguardUpdateMonitor.getCurrentUser();
+        boolean secure = mLockPatternUtils.isSecure(user);
         boolean currentlyInsecure = !secure ||  mKeyguardUpdateMonitor.getUserHasTrust(user);
         boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
         boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index b4e4773..8f83daa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * 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.
@@ -35,11 +35,16 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Stack;
 import java.util.TreeSet;
 
+/**
+ * A manager which handles heads up notifications which is a special mode where
+ * they simply peek from the top of the screen.
+ */
 public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsListener {
     private static final String TAG = "HeadsUpManager";
     private static final boolean DEBUG = false;
@@ -48,7 +53,7 @@
     private final int mHeadsUpNotificationDecay;
     private final int mMinimumDisplayTime;
 
-    private final int mTouchSensitivityDelay;
+    private final int mTouchAcceptanceDelay;
     private final ArrayMap<String, Long> mSnoozedPackages;
     private final HashSet<OnHeadsUpChangedListener> mListeners = new HashSet<>();
     private final int mDefaultSnoozeLengthMs;
@@ -67,13 +72,12 @@
 
         @Override
         public boolean release(HeadsUpEntry instance) {
-            instance.removeAutoCancelCallbacks();
+            instance.reset();
             mPoolObjects.push(instance);
             return true;
         }
     };
 
-
     private PhoneStatusBar mBar;
     private int mSnoozeLengthMs;
     private ContentObserver mSettingsObserver;
@@ -86,13 +90,12 @@
     private boolean mTrackingHeadsUp;
     private HashSet<NotificationData.Entry> mEntriesToRemoveAfterExpand = new HashSet<>();
     private boolean mIsExpanded;
-    private boolean mHasPinnedHeadsUp;
+    private boolean mHasPinnedNotification;
     private int[] mTmpTwoArray = new int[2];
 
     public HeadsUpManager(final Context context, ViewTreeObserver observer) {
         Resources resources = context.getResources();
-        mTouchSensitivityDelay = resources.getInteger(R.integer.heads_up_sensitivity_delay);
-        if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
+        mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay);
         mSnoozedPackages = new ArrayMap<>();
         mDefaultSnoozeLengthMs = resources.getInteger(R.integer.heads_up_default_snooze_length_ms);
         mSnoozeLengthMs = mDefaultSnoozeLengthMs;
@@ -116,7 +119,6 @@
         context.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), false,
                 mSettingsObserver);
-        if (DEBUG) Log.v(TAG, "mSnoozeLengthMs = " + mSnoozeLengthMs);
         observer.addOnComputeInternalInsetsListener(this);
     }
 
@@ -154,7 +156,7 @@
         if (alert) {
             HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key);
             headsUpEntry.updateEntry();
-            setEntryToShade(headsUpEntry, mIsExpanded, false /* justAdded */, false);
+            setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
         }
     }
 
@@ -165,22 +167,23 @@
         headsUpEntry.setEntry(entry);
         mHeadsUpEntries.put(entry.key, headsUpEntry);
         entry.row.setHeadsUp(true);
-        setEntryToShade(headsUpEntry, mIsExpanded /* inShade */, true /* justAdded */, false);
+        setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
         for (OnHeadsUpChangedListener listener : mListeners) {
-            listener.OnHeadsUpStateChanged(entry, true);
+            listener.onHeadsUpStateChanged(entry, true);
         }
         entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
     }
 
-    private void setEntryToShade(HeadsUpEntry headsUpEntry, boolean inShade, boolean justAdded,
-            boolean forceImmediate) {
+    private void setEntryPinned(HeadsUpEntry headsUpEntry, boolean isPinned) {
         ExpandableNotificationRow row = headsUpEntry.entry.row;
-        if (row.isInShade() != inShade || justAdded) {
-            row.setInShade(inShade);
-            if (!justAdded || !inShade) {
-                updatePinnedHeadsUpState(forceImmediate);
-                for (OnHeadsUpChangedListener listener : mListeners) {
-                    listener.OnHeadsUpPinnedChanged(row, !inShade);
+        if (row.isPinned() != isPinned) {
+            row.setPinned(isPinned);
+            updatePinnedMode();
+            for (OnHeadsUpChangedListener listener : mListeners) {
+                if (isPinned) {
+                    listener.onHeadsUpPinned(row);
+                } else {
+                    listener.onHeadsUpUnPinned(row);
                 }
             }
         }
@@ -189,24 +192,23 @@
     private void removeHeadsUpEntry(NotificationData.Entry entry) {
         HeadsUpEntry remove = mHeadsUpEntries.remove(entry.key);
         mSortedEntries.remove(remove);
-        mEntryPool.release(remove);
         entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
         entry.row.setHeadsUp(false);
-        setEntryToShade(remove, true /* inShade */, false /* justAdded */,
-                false /* forceImmediate */);
+        setEntryPinned(remove, false /* isPinned */);
         for (OnHeadsUpChangedListener listener : mListeners) {
-            listener.OnHeadsUpStateChanged(entry, false);
+            listener.onHeadsUpStateChanged(entry, false);
         }
+        mEntryPool.release(remove);
     }
 
-    private void updatePinnedHeadsUpState(boolean forceImmediate) {
-        boolean hasPinnedHeadsUp = hasPinnedHeadsUpInternal();
-        if (hasPinnedHeadsUp == mHasPinnedHeadsUp) {
+    private void updatePinnedMode() {
+        boolean hasPinnedNotification = hasPinnedNotificationInternal();
+        if (hasPinnedNotification == mHasPinnedNotification) {
             return;
         }
-        mHasPinnedHeadsUp = hasPinnedHeadsUp;
-        for (OnHeadsUpChangedListener listener :mListeners) {
-            listener.OnPinnedHeadsUpExistChanged(hasPinnedHeadsUp, forceImmediate);
+        mHasPinnedNotification = hasPinnedNotification;
+        for (OnHeadsUpChangedListener listener : mListeners) {
+            listener.onPinnedModeChanged(hasPinnedNotification);
         }
     }
 
@@ -222,7 +224,7 @@
             releaseImmediately(key);
             return true;
         } else {
-            getHeadsUpEntry(key).hideAsSoonAsPossible();
+            getHeadsUpEntry(key).removeAsSoonAsPossible();
             return false;
         }
     }
@@ -245,14 +247,13 @@
         return mHeadsUpEntries.containsKey(key);
     }
 
-
     /**
      * Push any current Heads Up notification down into the shade.
      */
     public void releaseAllImmediately() {
         if (DEBUG) Log.v(TAG, "releaseAllImmediately");
-        HashSet<String> keys = new HashSet<>(mHeadsUpEntries.keySet());
-        for (String key: keys) {
+        ArrayList<String> keys = new ArrayList<>(mHeadsUpEntries.keySet());
+        for (String key : keys) {
             releaseImmediately(key);
         }
     }
@@ -280,7 +281,7 @@
     }
 
     public void snooze() {
-        for (String key: mHeadsUpEntries.keySet()) {
+        for (String key : mHeadsUpEntries.keySet()) {
             HeadsUpEntry entry = mHeadsUpEntries.get(key);
             String packageName = entry.entry.notification.getPackageName();
             mSnoozedPackages.put(snoozeKey(packageName, mUser),
@@ -310,8 +311,11 @@
     }
 
     /**
+     * Decides whether a click is invalid for a notification, i.e it has not been shown long enough
+     * that a user might have consciously clicked on it.
+     *
      * @param key the key of the touched notification
-     * @return whether the touch is valid and should not be discarded
+     * @return whether the touch is invalid and should be discarded
      */
     public boolean shouldSwallowClick(String key) {
         HeadsUpEntry entry = mHeadsUpEntries.get(key);
@@ -322,14 +326,14 @@
     }
 
     public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
-        if (!mIsExpanded && mHasPinnedHeadsUp) {
+        if (!mIsExpanded && mHasPinnedNotification) {
             int minX = Integer.MAX_VALUE;
             int maxX = 0;
             int minY = Integer.MAX_VALUE;
             int maxY = 0;
-            for (HeadsUpEntry entry: mSortedEntries) {
+            for (HeadsUpEntry entry : mSortedEntries) {
                 ExpandableNotificationRow row = entry.entry.row;
-                if (!row.isInShade()) {
+                if (row.isPinned()) {
                     row.getLocationOnScreen(mTmpTwoArray);
                     minX = Math.min(minX, mTmpTwoArray[0]);
                     minY = Math.min(minY, 0);
@@ -349,7 +353,7 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("HeadsUpManager state:");
-        pw.print("  mTouchSensitivityDelay="); pw.println(mTouchSensitivityDelay);
+        pw.print("  mTouchAcceptanceDelay="); pw.println(mTouchAcceptanceDelay);
         pw.print("  mSnoozeLengthMs="); pw.println(mSnoozeLengthMs);
         pw.print("  now="); pw.println(SystemClock.elapsedRealtime());
         pw.print("  mUser="); pw.println(mUser);
@@ -365,38 +369,32 @@
     }
 
     public boolean hasPinnedHeadsUp() {
-        return mHasPinnedHeadsUp;
+        return mHasPinnedNotification;
     }
 
-    private boolean hasPinnedHeadsUpInternal() {
-        for (String key: mHeadsUpEntries.keySet()) {
+    private boolean hasPinnedNotificationInternal() {
+        for (String key : mHeadsUpEntries.keySet()) {
             HeadsUpEntry entry = mHeadsUpEntries.get(key);
-            if (!entry.entry.row.isInShade()) {
+            if (entry.entry.row.isPinned()) {
                 return true;
             }
         }
         return false;
     }
 
-    public void addSwipedOutKey(String key) {
+    /**
+     * Notifies that a notification was swiped out and will be removed.
+     *
+     * @param key the notification key
+     */
+    public void addSwipedOutNotification(String key) {
         mSwipedOutKeys.add(key);
     }
 
-    public float getHighestPinnedHeadsUp() {
-        float max = 0;
-        for (HeadsUpEntry entry: mSortedEntries) {
-            if (!entry.entry.row.isInShade()) {
-                max = Math.max(max, entry.entry.row.getActualHeight());
-            }
-        }
-        return max;
-    }
-
-    public void releaseAllToShade() {
-        for (String key: mHeadsUpEntries.keySet()) {
+    public void unpinAll() {
+        for (String key : mHeadsUpEntries.keySet()) {
             HeadsUpEntry entry = mHeadsUpEntries.get(key);
-            setEntryToShade(entry, true /* toShade */, false /* justAdded */,
-                    true /* forceImmediate */);
+            setEntryPinned(entry, false /* isPinned */);
         }
     }
 
@@ -420,7 +418,7 @@
         if (isExpanded != mIsExpanded) {
             mIsExpanded = isExpanded;
             if (isExpanded) {
-                releaseAllToShade();
+                unpinAll();
             }
         }
     }
@@ -430,6 +428,12 @@
         return topEntry != null ? topEntry.entry.row.getHeadsUpHeight() : 0;
     }
 
+    /**
+     * Compare two entries and decide how they should be ranked.
+     *
+     * @return -1 if the first argument should be ranked higher than the second, 1 if the second
+     * one should be ranked higher and 0 if they are equal.
+     */
     public int compare(NotificationData.Entry a, NotificationData.Entry b) {
         HeadsUpEntry aEntry = getHeadsUpEntry(a.key);
         HeadsUpEntry bEntry = getHeadsUpEntry(b.key);
@@ -439,6 +443,11 @@
         return aEntry.compareTo(bEntry);
     }
 
+
+    /**
+     * This represents a notification and how long it is in a heads up mode. It also manages its
+     * lifecycle automatically when created.
+     */
     public class HeadsUpEntry implements Comparable<HeadsUpEntry> {
         public NotificationData.Entry entry;
         public long postTime;
@@ -449,7 +458,7 @@
             this.entry = entry;
 
             // The actual post time will be just after the heads-up really slided in
-            postTime = mClock.currentTimeMillis() + mTouchSensitivityDelay;
+            postTime = mClock.currentTimeMillis() + mTouchAcceptanceDelay;
             mRemoveHeadsUpRunnable = new Runnable() {
                 @Override
                 public void run() {
@@ -467,7 +476,7 @@
             long currentTime = mClock.currentTimeMillis();
             earliestRemovaltime = currentTime + mMinimumDisplayTime;
             postTime = Math.max(postTime, currentTime);
-            removeAutoCancelCallbacks();
+            removeAutoRemovalCallbacks();
             if (canEntryDecay()) {
                 long finishTime = postTime + mHeadsUpNotificationDecay;
                 long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
@@ -487,7 +496,7 @@
                             : -1;
         }
 
-        public void removeAutoCancelCallbacks() {
+        public void removeAutoRemovalCallbacks() {
             mHandler.removeCallbacks(mRemoveHeadsUpRunnable);
         }
 
@@ -495,11 +504,17 @@
             return earliestRemovaltime < mClock.currentTimeMillis();
         }
 
-        public void hideAsSoonAsPossible() {
-            removeAutoCancelCallbacks();
+        public void removeAsSoonAsPossible() {
+            removeAutoRemovalCallbacks();
             mHandler.postDelayed(mRemoveHeadsUpRunnable,
                     earliestRemovaltime - mClock.currentTimeMillis());
         }
+
+        public void reset() {
+            removeAutoRemovalCallbacks();
+            entry = null;
+            mRemoveHeadsUpRunnable = null;
+        }
     }
 
     /**
@@ -519,8 +534,29 @@
     }
 
     public interface OnHeadsUpChangedListener {
-        void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly);
-        void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp);
-        void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp);
+        /**
+         * The state whether there exist pinned heads-ups or not changed.
+         *
+         * @param inPinnedMode whether there are any pinned heads-ups
+         */
+        void onPinnedModeChanged(boolean inPinnedMode);
+
+        /**
+         * A notification was just pinned to the top.
+         */
+        void onHeadsUpPinned(ExpandableNotificationRow headsUp);
+
+        /**
+         * A notification was just unpinned from the top.
+         */
+        void onHeadsUpUnPinned(ExpandableNotificationRow headsUp);
+
+        /**
+         * A notification just became a heads up or turned back to its normal state.
+         *
+         * @param entry the entry of the changed notification
+         * @param isHeadsUp whether the notification is now a headsUp notification
+         */
+        void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
index 0dce82f..5d89e2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
@@ -26,6 +26,7 @@
 import android.view.View;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.statusbar.phone.KeyguardPreviewContainer;
 
 import java.util.List;
@@ -80,13 +81,13 @@
         WidgetInfo info = new WidgetInfo();
         PackageManager packageManager = mContext.getPackageManager();
         final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
-                intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+                intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser());
         if (appList.size() == 0) {
             return null;
         }
         ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
                 PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
-                mLockPatternUtils.getCurrentUser());
+                KeyguardUpdateMonitor.getCurrentUser());
         if (wouldLaunchResolverActivity(resolved, appList)) {
             return null;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
index 67cc788..9d84a85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
@@ -35,6 +35,7 @@
     boolean isZenAvailable();
     ComponentName getEffectsSuppressor();
     boolean isCountdownConditionSupported();
+    int getCurrentUser();
 
     public static class Callback {
         public void onZenChanged(int zen) {}
@@ -45,4 +46,5 @@
         public void onManualRuleChanged(ZenRule rule) {}
         public void onConfigChanged(ZenModeConfig config) {}
     }
+
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 830a197..5b80ac2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -159,6 +160,11 @@
                 .isSystemConditionProviderEnabled(ZenModeConfig.COUNTDOWN_PATH);
     }
 
+    @Override
+    public int getCurrentUser() {
+        return ActivityManager.getCurrentUser();
+    }
+
     private void fireNextAlarmChanged() {
         for (Callback cb : mCallbacks) {
             cb.onNextAlarmChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java
new file mode 100644
index 0000000..05c0099
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.stack;
+
+import android.graphics.Path;
+import android.view.animation.PathInterpolator;
+
+/**
+ * An interpolator specifically designed for the appear animation of heads up notifications.
+ */
+public class HeadsUpAppearInterpolator extends PathInterpolator {
+    public HeadsUpAppearInterpolator() {
+        super(getAppearPath());
+    }
+
+    private static Path getAppearPath() {
+        Path path = new Path();
+        path.moveTo(0, 0);
+        float x1 = 250f;
+        float x2 = 150f;
+        float x3 = 100f;
+        float y1 = 90f;
+        float y2 = 78f;
+        float y3 = 80f;
+        float xTot = (x1 + x2 + x3);
+        path.cubicTo(x1 * 0.9f / xTot, 0f,
+                x1 * 0.8f / xTot, y1 / y3,
+                x1 / xTot , y1 / y3);
+        path.cubicTo((x1 + x2 * 0.4f) / xTot, y1 / y3,
+                (x1 + x2 * 0.2f) / xTot, y2 / y3,
+                (x1 + x2) / xTot, y2 / y3);
+        path.cubicTo((x1 + x2 + x3 * 0.4f) / xTot, y2 / y3,
+                (x1 + x2 + x3 * 0.2f) / xTot, 1f,
+                1f, 1f);
+        return path;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 88fc602..a1b0cae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -204,7 +204,6 @@
     private ViewGroup mScrollView;
     private boolean mInterceptDelegateEnabled;
     private boolean mDelegateToScrollView;
-
     private boolean mDisallowScrollingInThisMotion;
     private long mGoToFullShadeDelay;
     private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
@@ -487,9 +486,9 @@
         int stackHeight;
         float paddingOffset;
         boolean trackingHeadsUp = mTrackingHeadsUp;
-        int normalExpandPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight()
+        int normalUnfoldPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight()
                 : minStackHeight;
-        if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalExpandPositionStart
+        if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalUnfoldPositionStart
                 || getNotGoneChildCount() == 0) {
             paddingOffset = mTopPaddingOverflow;
             stackHeight = newStackHeight;
@@ -582,7 +581,7 @@
         if (v instanceof ExpandableNotificationRow) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) v;
             if (row.isHeadsUp()) {
-                mHeadsUpManager.addSwipedOutKey(row.getStatusBarNotification().getKey());
+                mHeadsUpManager.addSwipedOutNotification(row.getStatusBarNotification().getKey());
             }
         }
         final View veto = v.findViewById(R.id.veto);
@@ -626,10 +625,10 @@
         requestChildrenUpdate();
     }
 
-    public boolean isPinnedHeadsUp(View v) {
+    public static boolean isPinnedHeadsUp(View v) {
         if (v instanceof ExpandableNotificationRow) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) v;
-            return row.isHeadsUp() && !row.isInShade();
+            return row.isHeadsUp() && row.isPinned();
         }
         return false;
     }
@@ -711,7 +710,7 @@
             if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
                 if (slidingChild instanceof ExpandableNotificationRow) {
                     ExpandableNotificationRow row = (ExpandableNotificationRow) slidingChild;
-                    if (row.isHeadsUp() && !row.isInShade()
+                    if (row.isHeadsUp() && row.isPinned()
                             && mHeadsUpManager.getTopEntry().entry.row != row) {
                         continue;
                     }
@@ -812,7 +811,8 @@
         }
         handleEmptySpaceClick(ev);
         boolean expandWantsIt = false;
-        if (!mSwipingInProgress && !mOnlyScrollingInThisMotion && isScrollingEnabled()) {
+        if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion
+                && isScrollingEnabled()) {
             if (isCancelOrUp) {
                 mExpandHelper.onlyObserveMovements(false);
             }
@@ -824,7 +824,8 @@
             }
         }
         boolean scrollerWantsIt = false;
-        if (!mSwipingInProgress && !mExpandingNotification && !mDisallowScrollingInThisMotion) {
+        if (mIsExpanded && !mSwipingInProgress && !mExpandingNotification
+                && !mDisallowScrollingInThisMotion) {
             scrollerWantsIt = onScrollTouch(ev);
         }
         boolean horizontalSwipeWantsIt = false;
@@ -1872,15 +1873,15 @@
             boolean onBottom = false;
             if (!mIsExpanded && !isHeadsUp) {
                 type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
-            } else if (mAddedHeadsUpChildren.contains(row) || (!row.isInShade() && !mIsExpanded)) {
-                if (!row.isInShade() || shouldHunAppearFromBottom(row)) {
+            } else if (mAddedHeadsUpChildren.contains(row) || (row.isPinned() && !mIsExpanded)) {
+                if (row.isPinned() || shouldHunAppearFromBottom(row)) {
                     // Our custom add animation
                     type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR;
                 } else {
                     // Normal add animation
                     type = AnimationEvent.ANIMATION_TYPE_ADD;
                 }
-                onBottom = row.isInShade();
+                onBottom = !row.isPinned();
             }
             AnimationEvent event = new AnimationEvent(row, type);
             event.headsUpFromBottom = onBottom;
@@ -2670,7 +2671,7 @@
         }
     }
 
-    public void performOnAnimationFinished(Runnable runnable) {
+    public void runAfterAnimationFinished(Runnable runnable) {
         mAnimationFinishedRunnables.add(runnable);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 2a49a4c..202063a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -311,7 +311,8 @@
                     StackViewState viewState = resultState.getViewStateForView(
                             nextChild);
                     // The child below the dragged one must be fully visible
-                    if (!isPinnedHeadsUpView(draggedView) || isPinnedHeadsUpView(nextChild)) {
+                    if (!NotificationStackScrollLayout.isPinnedHeadsUp(draggedView)
+                            || NotificationStackScrollLayout.isPinnedHeadsUp(nextChild)) {
                         viewState.alpha = 1;
                     }
                 }
@@ -324,14 +325,6 @@
         }
     }
 
-    private boolean isPinnedHeadsUpView(View view) {
-        if (view instanceof ExpandableNotificationRow) {
-            ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-            return row.isHeadsUp() && !row.isInShade();
-        }
-        return false;
-    }
-
     /**
      * Update the visible children on the state.
      */
@@ -380,7 +373,7 @@
     /**
      * Determine the positions for the views. This is the main part of the algorithm.
      *
-     *  @param resultState The result state to update if a change to the properties of a child occurs
+     * @param resultState The result state to update if a change to the properties of a child occurs
      * @param algorithmState The state in which the current pass of the algorithm is currently in
      * @param ambientState The current ambient state
      */
@@ -515,11 +508,12 @@
             }
             StackViewState childState = resultState.getViewStateForView(row);
             boolean isTopEntry = topHeadsUpEntry == row;
-            if (!row.isInShade()) {
+            if (row.isPinned()) {
                 childState.yTranslation = 0;
                 childState.height = row.getHeadsUpHeight();
                 if (!isTopEntry) {
-                    // Ensure that a headsUp is never below the topmost headsUp
+                    // Ensure that a headsUp doesn't vertically extend further than the heads-up at
+                    // the top most z-position
                     StackViewState topState = resultState.getViewStateForView(topHeadsUpEntry);
                     childState.height = row.getHeadsUpHeight();
                     childState.yTranslation = topState.yTranslation + topState.height
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index f5d94c8..b9466d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -21,11 +21,9 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
-import android.graphics.Path;
 import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -78,6 +76,7 @@
     private final Interpolator mFastOutSlowInInterpolator;
     private final Interpolator mHeadsUpAppearInterpolator;
     private final int mGoToFullShadeAppearingTranslation;
+    private final StackViewState mTmpState = new StackViewState();
     public NotificationStackScrollLayout mHostLayout;
     private ArrayList<NotificationStackScrollLayout.AnimationEvent> mNewEvents =
             new ArrayList<>();
@@ -95,7 +94,6 @@
     private ValueAnimator mTopOverScrollAnimator;
     private ValueAnimator mBottomOverScrollAnimator;
     private ExpandableNotificationRow mChildExpandingView;
-    private StackViewState mTmpState = new StackViewState();
     private int mHeadsUpAppearHeightBottom;
     private boolean mShadeExpanded;
 
@@ -106,25 +104,7 @@
         mGoToFullShadeAppearingTranslation =
                 hostLayout.getContext().getResources().getDimensionPixelSize(
                         R.dimen.go_to_full_shade_appearing_translation);
-        Path path = new Path();
-        path.moveTo(0, 0);
-        float x1 = 250f;
-        float x2 = 150f;
-        float x3 = 100f;
-        float y1 = 90f;
-        float y2 = 78f;
-        float y3 = 80f;
-        float xTot = (x1 + x2 + x3);
-        path.cubicTo(x1 * 0.9f / xTot, 0f,
-                x1 * 0.8f / xTot, y1 / y3,
-                x1 / xTot , y1 / y3);
-        path.cubicTo((x1 + x2 * 0.4f) / xTot, y1 / y3,
-                (x1 + x2 * 0.2f) / xTot, y2 / y3,
-                (x1 + x2) / xTot, y2 / y3);
-        path.cubicTo((x1 + x2 + x3 * 0.4f) / xTot, y2 / y3,
-                (x1 + x2 + x3 * 0.2f) / xTot, 1f,
-                1f, 1f);
-        mHeadsUpAppearInterpolator = new PathInterpolator(path);
+        mHeadsUpAppearInterpolator = new HeadsUpAppearInterpolator();
     }
 
     public boolean isRunning() {
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 dce695d..a5684a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -59,7 +59,7 @@
     }
 
     @Override
-    public void disable(int state, boolean animate) {
+    public void disable(int state1, int state2, boolean animate) {
     }
 
     @Override
@@ -121,7 +121,7 @@
     }
 
     @Override
-    public void escalateHeadsUp() {
+    public void maybeEscalateHeadsUp() {
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 240c210..deed895 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -24,11 +24,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.MoveCallback;
+import android.os.Handler;
 import android.os.UserHandle;
 import android.os.storage.DiskInfo;
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.Log;
 
 import com.android.internal.R;
@@ -39,12 +45,14 @@
 public class StorageNotification extends SystemUI {
     private static final String TAG = "StorageNotification";
 
-    private static final int NOTIF_ID = 0x53544f52; // STOR
+    private static final int PUBLIC_ID = 0x53505542; // SPUB
+    private static final int PRIVATE_ID = 0x53505256; // SPRV
+    private static final int DISK_ID = 0x5344534b; // SDSK
+    private static final int MOVE_ID = 0x534d4f56; // SMOV
 
     private static final String ACTION_SNOOZE_VOLUME = "com.android.systemui.action.SNOOZE_VOLUME";
 
     // TODO: delay some notifications to avoid bumpy fast operations
-    // TODO: annoy user when private media is missing
 
     private NotificationManager mNotificationManager;
     private StorageManager mStorageManager;
@@ -52,17 +60,29 @@
     private final StorageEventListener mListener = new StorageEventListener() {
         @Override
         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
-            onVolumeStateChangedInternal(vol, oldState, newState);
+            onVolumeStateChangedInternal(vol);
         }
 
         @Override
-        public void onVolumeMetadataChanged(VolumeInfo vol) {
+        public void onVolumeMetadataChanged(String fsUuid) {
             // Avoid kicking notifications when getting early metadata before
             // mounted. If already mounted, we're being kicked because of a
             // nickname or init'ed change.
-            if (vol.isMountedReadable()) {
-                onVolumeStateChangedInternal(vol, vol.getState(), vol.getState());
+            final VolumeInfo vol = mStorageManager.findVolumeByUuid(fsUuid);
+            if (vol != null && vol.isMountedReadable()) {
+                onVolumeStateChangedInternal(vol);
             }
+
+            final VolumeRecord rec = mStorageManager.findRecordByUuid(fsUuid);
+            if (rec == null) {
+                // Private volume was probably just forgotten
+                mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
+            }
+        }
+
+        @Override
+        public void onDiskScanned(DiskInfo disk, int volumeCount) {
+            onDiskScannedInternal(disk, volumeCount);
         }
     };
 
@@ -70,8 +90,19 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             // TODO: kick this onto background thread
-            final String volId = intent.getStringExtra(VolumeInfo.EXTRA_VOLUME_ID);
-            mStorageManager.setVolumeSnoozed(volId, true);
+            final String fsUuid = intent.getStringExtra(VolumeRecord.EXTRA_FS_UUID);
+            mStorageManager.setVolumeSnoozed(fsUuid, true);
+        }
+    };
+
+    private final MoveCallback mMoveCallback = new MoveCallback() {
+        @Override
+        public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
+            if (PackageManager.isMoveStatusFinished(status)) {
+                onMoveFinished(moveId, moveTitle, status);
+            } else {
+                onMoveProgress(moveId, moveTitle, status, estMillis);
+            }
         }
     };
 
@@ -88,20 +119,99 @@
         // Kick current state into place
         final List<VolumeInfo> vols = mStorageManager.getVolumes();
         for (VolumeInfo vol : vols) {
-            onVolumeStateChangedInternal(vol, vol.getState(), vol.getState());
+            onVolumeStateChangedInternal(vol);
+        }
+
+        mContext.getPackageManager().registerMoveCallback(mMoveCallback, new Handler());
+
+        updateMissingPrivateVolumes();
+    }
+
+    private void updateMissingPrivateVolumes() {
+        final List<VolumeRecord> recs = mStorageManager.getVolumeRecords();
+        for (VolumeRecord rec : recs) {
+            if (rec.getType() != VolumeInfo.TYPE_PRIVATE) continue;
+
+            final String fsUuid = rec.getFsUuid();
+            final VolumeInfo info = mStorageManager.findVolumeByUuid(fsUuid);
+            if (info != null && info.isMountedWritable()) {
+                // Yay, private volume is here!
+                mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
+
+            } else {
+                // Boo, annoy the user to reinsert the private volume
+                final CharSequence title = mContext.getString(R.string.ext_media_missing_title,
+                        rec.getNickname());
+                final CharSequence text = mContext.getString(R.string.ext_media_missing_message);
+
+                final Notification notif = new Notification.Builder(mContext)
+                        .setSmallIcon(R.drawable.stat_notify_sdcard)
+                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(text)
+                        .setStyle(new Notification.BigTextStyle().bigText(text))
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setLocalOnly(true)
+                        .setContentIntent(buildForgetPendingIntent(rec))
+                        .setCategory(Notification.CATEGORY_SYSTEM)
+                        .setOngoing(true)
+                        .build();
+
+                mNotificationManager.notifyAsUser(fsUuid, PRIVATE_ID, notif, UserHandle.ALL);
+            }
         }
     }
 
-    public void onVolumeStateChangedInternal(VolumeInfo vol, int oldState, int newState) {
-        // We only care about public volumes
-        if (vol.getType() != VolumeInfo.TYPE_PUBLIC) {
-            return;
-        }
+    private void onDiskScannedInternal(DiskInfo disk, int volumeCount) {
+        if (volumeCount == 0) {
+            // No supported volumes found, give user option to format
+            final CharSequence title = mContext.getString(
+                    R.string.ext_media_unmountable_notification_title, disk.getDescription());
+            final CharSequence text = mContext.getString(
+                    R.string.ext_media_unmountable_notification_message, disk.getDescription());
 
-        Log.d(TAG, vol.toString());
+            final Notification notif = new Notification.Builder(mContext)
+                    .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
+                    .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                    .setContentTitle(title)
+                    .setContentText(text)
+                    .setStyle(new Notification.BigTextStyle().bigText(text))
+                    .setVisibility(Notification.VISIBILITY_PUBLIC)
+                    .setLocalOnly(true)
+                    .setContentIntent(buildInitPendingIntent(disk))
+                    .setCategory(Notification.CATEGORY_ERROR)
+                    .build();
+
+            mNotificationManager.notifyAsUser(disk.getId(), DISK_ID, notif, UserHandle.ALL);
+
+        } else {
+            // Yay, we have volumes!
+            mNotificationManager.cancelAsUser(disk.getId(), DISK_ID, UserHandle.ALL);
+        }
+    }
+
+    private void onVolumeStateChangedInternal(VolumeInfo vol) {
+        switch (vol.getType()) {
+            case VolumeInfo.TYPE_PRIVATE:
+                onPrivateVolumeStateChangedInternal(vol);
+                break;
+            case VolumeInfo.TYPE_PUBLIC:
+                onPublicVolumeStateChangedInternal(vol);
+                break;
+        }
+    }
+
+    private void onPrivateVolumeStateChangedInternal(VolumeInfo vol) {
+        Log.d(TAG, "Notifying about private volume: " + vol.toString());
+
+        updateMissingPrivateVolumes();
+    }
+
+    private void onPublicVolumeStateChangedInternal(VolumeInfo vol) {
+        Log.d(TAG, "Notifying about public volume: " + vol.toString());
 
         final Notification notif;
-        switch (newState) {
+        switch (vol.getState()) {
             case VolumeInfo.STATE_UNMOUNTED:
                 notif = onVolumeUnmounted(vol);
                 break;
@@ -133,9 +243,9 @@
         }
 
         if (notif != null) {
-            mNotificationManager.notifyAsUser(vol.getId(), NOTIF_ID, notif, UserHandle.ALL);
+            mNotificationManager.notifyAsUser(vol.getId(), PUBLIC_ID, notif, UserHandle.ALL);
         } else {
-            mNotificationManager.cancelAsUser(vol.getId(), NOTIF_ID, UserHandle.ALL);
+            mNotificationManager.cancelAsUser(vol.getId(), PUBLIC_ID, UserHandle.ALL);
         }
     }
 
@@ -159,20 +269,24 @@
     }
 
     private Notification onVolumeMounted(VolumeInfo vol) {
+        final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
+
         // Don't annoy when user dismissed in past
-        if (vol.isSnoozed()) return null;
+        if (rec.isSnoozed()) return null;
 
         final DiskInfo disk = vol.getDisk();
-        if (disk.isAdoptable() && !vol.isInited()) {
+        if (disk.isAdoptable() && !rec.isInited()) {
             final CharSequence title = disk.getDescription();
             final CharSequence text = mContext.getString(
                     R.string.ext_media_new_notification_message, disk.getDescription());
 
+            final PendingIntent initAction = buildInitPendingIntent(vol);
             return buildNotificationBuilder(vol, title, text)
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_init_action),
-                            buildInitPendingIntent(vol)))
+                            initAction))
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
                             buildUnmountPendingIntent(vol)))
+                    .setContentIntent(initAction)
                     .setDeleteIntent(buildSnoozeIntent(vol))
                     .setCategory(Notification.CATEGORY_SYSTEM)
                     .build();
@@ -182,11 +296,13 @@
             final CharSequence text = mContext.getString(
                     R.string.ext_media_ready_notification_message, disk.getDescription());
 
+            final PendingIntent browseAction = buildBrowsePendingIntent(vol);
             return buildNotificationBuilder(vol, title, text)
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_browse_action),
-                            buildBrowsePendingIntent(vol)))
+                            browseAction))
                     .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
                             buildUnmountPendingIntent(vol)))
+                    .setContentIntent(browseAction)
                     .setDeleteIntent(buildSnoozeIntent(vol))
                     .setCategory(Notification.CATEGORY_SYSTEM)
                     .setPriority(Notification.PRIORITY_LOW)
@@ -260,16 +376,84 @@
                 .build();
     }
 
-    private int getSmallIcon(VolumeInfo vol) {
-        if (vol.disk.isSd()) {
-            switch (vol.getState()) {
+    private void onMoveProgress(int moveId, String moveTitle, int status, long estMillis) {
+        final CharSequence title;
+        if (!TextUtils.isEmpty(moveTitle)) {
+            title = mContext.getString(R.string.ext_media_move_specific_title, moveTitle);
+        } else {
+            title = mContext.getString(R.string.ext_media_move_title);
+        }
+
+        final CharSequence text;
+        if (estMillis < 0) {
+            text = null;
+        } else {
+            text = DateUtils.formatDuration(estMillis);
+        }
+
+        final Notification notif = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.stat_notify_sdcard)
+                .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                .setContentTitle(title)
+                .setContentText(text)
+                .setStyle(new Notification.BigTextStyle().bigText(text))
+                .setVisibility(Notification.VISIBILITY_PUBLIC)
+                .setLocalOnly(true)
+                .setCategory(Notification.CATEGORY_PROGRESS)
+                .setPriority(Notification.PRIORITY_LOW)
+                .setProgress(100, status, false)
+                .setOngoing(true)
+                .build();
+
+        mNotificationManager.notifyAsUser(moveTitle, MOVE_ID, notif, UserHandle.ALL);
+    }
+
+    private void onMoveFinished(int moveId, String moveTitle, int status) {
+        if (!TextUtils.isEmpty(moveTitle)) {
+            // We currently ignore finished app moves; just clear the last
+            // published progress
+            mNotificationManager.cancelAsUser(moveTitle, MOVE_ID, UserHandle.ALL);
+            return;
+        }
+
+        final VolumeInfo vol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
+        final String descrip = mStorageManager.getBestVolumeDescription(vol);
+
+        final CharSequence title;
+        final CharSequence text;
+        if (status == PackageManager.MOVE_SUCCEEDED) {
+            title = mContext.getString(R.string.ext_media_move_success_title);
+            text = mContext.getString(R.string.ext_media_move_success_message, descrip);
+        } else {
+            title = mContext.getString(R.string.ext_media_move_failure_title);
+            text = mContext.getString(R.string.ext_media_move_failure_message);
+        }
+
+        final Notification notif = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.stat_notify_sdcard)
+                .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                .setContentTitle(title)
+                .setContentText(text)
+                .setStyle(new Notification.BigTextStyle().bigText(text))
+                .setVisibility(Notification.VISIBILITY_PUBLIC)
+                .setLocalOnly(true)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setPriority(Notification.PRIORITY_LOW)
+                .build();
+
+        mNotificationManager.notifyAsUser(moveTitle, MOVE_ID, notif, UserHandle.ALL);
+    }
+
+    private int getSmallIcon(DiskInfo disk, int state) {
+        if (disk.isSd()) {
+            switch (state) {
                 case VolumeInfo.STATE_CHECKING:
                 case VolumeInfo.STATE_EJECTING:
                     return R.drawable.stat_notify_sdcard_prepare;
                 default:
                     return R.drawable.stat_notify_sdcard;
             }
-        } else if (vol.disk.isUsb()) {
+        } else if (disk.isUsb()) {
             return R.drawable.stat_sys_data_usb;
         } else {
             return R.drawable.stat_notify_sdcard;
@@ -279,7 +463,7 @@
     private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
             CharSequence text) {
         return new Notification.Builder(mContext)
-                .setSmallIcon(getSmallIcon(vol))
+                .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
                 .setColor(mContext.getColor(R.color.system_notification_accent_color))
                 .setContentTitle(title)
                 .setContentText(text)
@@ -288,6 +472,17 @@
                 .setLocalOnly(true);
     }
 
+    private PendingIntent buildInitPendingIntent(DiskInfo disk) {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                "com.android.settings.deviceinfo.StorageWizardInit");
+        intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
+
+        final int requestKey = disk.getId().hashCode();
+        return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
+                PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+    }
+
     private PendingIntent buildInitPendingIntent(VolumeInfo vol) {
         final Intent intent = new Intent();
         intent.setClassName("com.android.settings",
@@ -321,7 +516,7 @@
     private PendingIntent buildDetailsPendingIntent(VolumeInfo vol) {
         final Intent intent = new Intent();
         intent.setClassName("com.android.settings",
-                "com.android.settings.Settings$StorageVolumeSettingsActivity");
+                "com.android.settings.Settings$PublicVolumeSettingsActivity");
         intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
 
         final int requestKey = vol.getId().hashCode();
@@ -331,10 +526,21 @@
 
     private PendingIntent buildSnoozeIntent(VolumeInfo vol) {
         final Intent intent = new Intent(ACTION_SNOOZE_VOLUME);
-        intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+        intent.putExtra(VolumeRecord.EXTRA_FS_UUID, vol.getFsUuid());
 
         final int requestKey = vol.getId().hashCode();
         return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
                 PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
     }
+
+    private PendingIntent buildForgetPendingIntent(VolumeRecord rec) {
+        final Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                "com.android.settings.Settings$PrivateVolumeForgetActivity");
+        intent.putExtra(VolumeRecord.EXTRA_FS_UUID, rec.getFsUuid());
+
+        final int requestKey = rec.getFsUuid().hashCode();
+        return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
+                PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
index 4f20ac7..f7cb9fe 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SegmentedButtons.java
@@ -17,6 +17,7 @@
 package com.android.systemui.volume;
 
 import android.content.Context;
+import android.graphics.Typeface;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -30,6 +31,8 @@
 
 public class SegmentedButtons extends LinearLayout {
     private static final int LABEL_RES_KEY = R.id.label;
+    private static final Typeface REGULAR = Typeface.create("sans-serif", Typeface.NORMAL);
+    private static final Typeface MEDIUM = Typeface.create("sans-serif-medium", Typeface.NORMAL);
 
     private final Context mContext;
     private final LayoutInflater mInflater;
@@ -60,6 +63,7 @@
             final Object tag = c.getTag();
             final boolean selected = Objects.equals(mSelectedValue, tag);
             c.setSelected(selected);
+            c.setTypeface(selected ? MEDIUM : REGULAR);
         }
         fireOnSelected();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Util.java b/packages/SystemUI/src/com/android/systemui/volume/Util.java
index 216a4da..4214091 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Util.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Util.java
@@ -144,9 +144,14 @@
         return HMMAA.format(new Date(millis));
     }
 
-    public static void setText(TextView tv, CharSequence text) {
-        if (Objects.equals(tv.getText(), text)) return;
+    private static CharSequence emptyToNull(CharSequence str) {
+        return str == null || str.length() == 0 ? null : str;
+    }
+
+    public static boolean setText(TextView tv, CharSequence text) {
+        if (Objects.equals(emptyToNull(tv.getText()), emptyToNull(text))) return false;
         tv.setText(text);
+        return true;
     }
 
     public static final void setVisOrGone(View v, boolean vis) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index bb4aa61..9434036 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -37,7 +37,6 @@
 import android.os.Message;
 import android.os.SystemClock;
 import android.provider.Settings.Global;
-import android.service.notification.ZenModeConfig;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.SparseBooleanArray;
@@ -52,7 +51,6 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.animation.DecelerateInterpolator;
-import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.SeekBar;
@@ -90,16 +88,12 @@
     private final ViewGroup mDialogView;
     private final ViewGroup mDialogContentView;
     private final ImageButton mExpandButton;
-    private final TextView mFootlineText;
-    private final Button mFootlineAction;
     private final View mSettingsButton;
-    private final View mFooter;
     private final List<VolumeRow> mRows = new ArrayList<VolumeRow>();
     private final SpTexts mSpTexts;
     private final SparseBooleanArray mDynamic = new SparseBooleanArray();
     private final KeyguardManager mKeyguard;
     private final int mExpandButtonAnimationDuration;
-    private final View mTextFooter;
     private final ZenFooter mZenFooter;
     private final LayoutTransition mLayoutTransition;
     private final Object mSafetyWarningLock = new Object();
@@ -108,8 +102,6 @@
     private boolean mExpanded;
     private int mActiveStream;
     private boolean mShowHeaders = VolumePrefs.DEFAULT_SHOW_HEADERS;
-    private boolean mShowFooter = VolumePrefs.DEFAULT_SHOW_FOOTER;
-    private boolean mShowZenFooter = VolumePrefs.DEFAULT_ZEN_FOOTER;
     private boolean mAutomute = VolumePrefs.DEFAULT_ENABLE_AUTOMUTE;
     private boolean mSilentMode = VolumePrefs.DEFAULT_ENABLE_SILENT_MODE;
     private State mState;
@@ -118,7 +110,7 @@
     private SafetyWarningDialog mSafetyWarning;
     private Callback mCallback;
 
-    public VolumeDialog(Context context, VolumeDialogController controller,
+    public VolumeDialog(Context context, int windowType, VolumeDialogController controller,
             ZenModeController zenModeController, Callback callback) {
         mContext = context;
         mController = controller;
@@ -141,7 +133,7 @@
         mDialog.setCanceledOnTouchOutside(true);
         final Resources res = mContext.getResources();
         final WindowManager.LayoutParams lp = window.getAttributes();
-        lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+        lp.type = windowType;
         lp.format = PixelFormat.TRANSLUCENT;
         lp.setTitle(VolumeDialog.class.getSimpleName());
         lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
@@ -176,17 +168,11 @@
         addRow(AudioManager.STREAM_SYSTEM,
                 R.drawable.ic_volume_system, R.drawable.ic_volume_system_mute, false);
 
-        mTextFooter = mDialog.findViewById(R.id.volume_text_footer);
-        mFootlineText = (TextView) mDialog.findViewById(R.id.volume_footline_text);
-        mSpTexts.add(mFootlineText);
-        mFootlineAction = (Button) mDialog.findViewById(R.id.volume_footline_action_button);
-        mSpTexts.add(mFootlineAction);
-        mFooter = mDialog.findViewById(R.id.volume_footer);
         mSettingsButton = mDialog.findViewById(R.id.volume_settings_button);
         mSettingsButton.setOnClickListener(mClickSettings);
         mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
         mZenFooter = (ZenFooter) mDialog.findViewById(R.id.volume_zen_footer);
-        mZenFooter.init(zenModeController, mZenFooterCallback);
+        mZenFooter.init(zenModeController);
 
         controller.addCallback(mControllerCallbackH, mHandler);
         controller.getState();
@@ -217,18 +203,6 @@
         mHandler.sendEmptyMessage(H.RECHECK_ALL);
     }
 
-    public void setShowFooter(boolean show) {
-        if (mShowFooter == show) return;
-        mShowFooter = show;
-        mHandler.sendEmptyMessage(H.RECHECK_ALL);
-    }
-
-    public void setZenFooter(boolean zen) {
-        if (mShowZenFooter == zen) return;
-        mShowZenFooter = zen;
-        mHandler.sendEmptyMessage(H.RECHECK_ALL);
-    }
-
     public void setAutomute(boolean automute) {
         if (mAutomute == automute) return;
         mAutomute = automute;
@@ -315,7 +289,6 @@
         writer.print("  mActiveStream: "); writer.println(mActiveStream);
         writer.print("  mDynamic: "); writer.println(mDynamic);
         writer.print("  mShowHeaders: "); writer.println(mShowHeaders);
-        writer.print("  mShowFooter: "); writer.println(mShowFooter);
         writer.print("  mAutomute: "); writer.println(mAutomute);
         writer.print("  mSilentMode: "); writer.println(mSilentMode);
     }
@@ -444,7 +417,6 @@
     }
 
     private int computeTimeoutH() {
-        if (mZenFooter != null && mZenFooter.isFooterExpanded()) return 10000;
         if (mSafetyWarning != null) return 5000;
         if (mExpanded || mExpanding) return 5000;
         if (mActiveStream == AudioManager.STREAM_MUSIC) return 1500;
@@ -515,18 +487,9 @@
         final VolumeRow activeRow = getActiveRow();
         updateFooterH();
         updateExpandButtonH();
-        final boolean footerVisible = mFooter.getVisibility() == View.VISIBLE;
         if (!mShowing) {
             trimObsoleteH();
         }
-        // first, find the last visible row
-        VolumeRow lastVisible = null;
-        for (VolumeRow row : mRows) {
-            final boolean isActive = row == activeRow;
-            if (isVisibleH(row, isActive)) {
-                lastVisible = row;
-            }
-        }
         // apply changes to all rows
         for (VolumeRow row : mRows) {
             final boolean isActive = row == activeRow;
@@ -542,8 +505,7 @@
                     row.settingsButton.setImageResource(expandButtonRes);
                 }
             }
-            Util.setVisOrInvis(row.settingsButton,
-                     mExpanded && (!footerVisible && row == lastVisible));
+            Util.setVisOrInvis(row.settingsButton, false);
             row.header.setAlpha(mExpanded && isActive ? 1 : 0.5f);
         }
     }
@@ -585,51 +547,9 @@
         updateFooterH();
     }
 
-    private void updateTextFooterH() {
-        final boolean zen = mState.zenMode != Global.ZEN_MODE_OFF;
-        final boolean wasVisible = mFooter.getVisibility() == View.VISIBLE;
-        Util.setVisOrGone(mTextFooter, mExpanded && mShowFooter && (zen || mShowing && wasVisible));
-        if (mTextFooter.getVisibility() == View.VISIBLE) {
-            String text = null;
-            String action = null;
-            if (mState.exitCondition != null) {
-                final long countdown = ZenModeConfig.tryParseCountdownConditionId(mState
-                        .exitCondition.id);
-                if (countdown != 0) {
-                    text = mContext.getString(R.string.volume_dnd_ends_at,
-                            Util.getShortTime(countdown));
-                    action = mContext.getString(R.string.volume_end_now);
-                }
-            }
-            if (text == null) {
-                text = mContext.getString(R.string.volume_dnd_is_on);
-            }
-            if (action == null) {
-                action = mContext.getString(R.string.volume_turn_off);
-            }
-            Util.setText(mFootlineText, text);
-            Util.setText(mFootlineAction, action);
-            mFootlineAction.setOnClickListener(mTurnOffDnd);
-        }
-        Util.setVisOrGone(mFootlineText, zen);
-        Util.setVisOrGone(mFootlineAction, zen);
-    }
-
     private void updateFooterH() {
-        if (!mShowFooter) {
-            Util.setVisOrGone(mFooter, false);
-            return;
-        }
-        if (mShowZenFooter) {
-            Util.setVisOrGone(mTextFooter, false);
-            final boolean ringActive = mActiveStream == AudioManager.STREAM_RING;
-            Util.setVisOrGone(mZenFooter, mZenFooter.isZen() && ringActive
-                    || mShowing && (mExpanded || mZenFooter.getVisibility() == View.VISIBLE));
-            mZenFooter.update();
-        } else {
-            Util.setVisOrGone(mZenFooter, false);
-            updateTextFooterH();
-        }
+        Util.setVisOrGone(mZenFooter, mState.zenMode != Global.ZEN_MODE_OFF);
+        mZenFooter.update();
     }
 
     private void updateVolumeRowH(VolumeRow row) {
@@ -642,12 +562,20 @@
         }
         final boolean isRingStream = row.stream == AudioManager.STREAM_RING;
         final boolean isSystemStream = row.stream == AudioManager.STREAM_SYSTEM;
+        final boolean isAlarmStream = row.stream == AudioManager.STREAM_ALARM;
+        final boolean isMusicStream = row.stream == AudioManager.STREAM_MUSIC;
         final boolean isRingVibrate = isRingStream
                 && mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;
-        final boolean isNoned = (isRingStream || isSystemStream)
-                && mState.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
-        final boolean isLimited = isRingStream
-                && mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        final boolean isRingSilent = isRingStream
+                && mState.ringerModeInternal == AudioManager.RINGER_MODE_SILENT;
+        final boolean isZenAlarms = mState.zenMode == Global.ZEN_MODE_ALARMS;
+        final boolean isZenNone = mState.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
+        final boolean isZenPriority = mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        final boolean isRingZenNone = (isRingStream || isSystemStream) && isZenNone;
+        final boolean isRingLimited = isRingStream && isZenPriority;
+        final boolean zenMuted = isZenAlarms ? (isRingStream || isSystemStream)
+                : isZenNone ? (isRingStream || isSystemStream || isAlarmStream || isMusicStream)
+                : false;
 
         // update slider max
         final int max = ss.levelMax * 100;
@@ -663,15 +591,15 @@
 
         // update header text
         final String text;
-        if (isNoned) {
+        if (isRingZenNone) {
             text = mContext.getString(R.string.volume_stream_muted_dnd, ss.name);
-        } else if (isRingVibrate && isLimited) {
+        } else if (isRingVibrate && isRingLimited) {
             text = mContext.getString(R.string.volume_stream_vibrate_dnd, ss.name);
         } else if (isRingVibrate) {
             text = mContext.getString(R.string.volume_stream_vibrate, ss.name);
         } else if (ss.muted || mAutomute && ss.level == 0) {
             text = mContext.getString(R.string.volume_stream_muted, ss.name);
-        } else if (isLimited) {
+        } else if (isRingLimited) {
             text = mContext.getString(R.string.volume_stream_limited_dnd, ss.name);
         } else {
             text = ss.name;
@@ -679,11 +607,12 @@
         Util.setText(row.header, text);
 
         // update icon
-        final boolean iconEnabled = mAutomute || ss.muteSupported;
+        final boolean iconEnabled = (mAutomute || ss.muteSupported) && !zenMuted;
         row.icon.setEnabled(iconEnabled);
         row.icon.setAlpha(iconEnabled ? 1 : 0.5f);
         final int iconRes =
                 isRingVibrate ? R.drawable.ic_volume_ringer_vibrate
+                : isRingSilent || zenMuted ? row.cachedIconRes
                 : ss.routedToBluetooth ?
                         (ss.muted ? R.drawable.ic_volume_media_bt_mute
                                 : R.drawable.ic_volume_media_bt)
@@ -705,10 +634,11 @@
                 : Events.ICON_STATE_UNKNOWN;
 
         // update slider
-        updateVolumeRowSliderH(row);
+        updateVolumeRowSliderH(row, zenMuted);
     }
 
-    private void updateVolumeRowSliderH(VolumeRow row) {
+    private void updateVolumeRowSliderH(VolumeRow row, boolean zenMuted) {
+        row.slider.setEnabled(!zenMuted);
         if (row.tracking) {
             return;  // don't update if user is sliding
         }
@@ -887,46 +817,6 @@
         }
     };
 
-    private final View.OnClickListener mTurnOffDnd = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            mSettingsButton.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    mController.setZenMode(Global.ZEN_MODE_OFF);
-                }
-            }, WAIT_FOR_RIPPLE);
-        }
-    };
-
-    private final ZenFooter.Callback mZenFooterCallback = new ZenFooter.Callback() {
-        @Override
-        public void onFooterExpanded() {
-            mHandler.sendEmptyMessage(H.RESCHEDULE_TIMEOUT);
-        }
-
-        @Override
-        public void onSettingsClicked() {
-            dismiss(Events.DISMISS_REASON_SETTINGS_CLICKED);
-            if (mCallback != null) {
-                mCallback.onZenSettingsClicked();
-            }
-        }
-
-        @Override
-        public void onDoneClicked() {
-            dismiss(Events.DISMISS_REASON_DONE_CLICKED);
-        }
-
-        @Override
-        public void onPrioritySettingsClicked() {
-            dismiss(Events.DISMISS_REASON_SETTINGS_CLICKED);
-            if (mCallback != null) {
-                mCallback.onZenPrioritySettingsClicked();
-            }
-        }
-    };
-
     private final class H extends Handler {
         private static final int SHOW = 1;
         private static final int DISMISS = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 86abfcc..1083f40 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.Settings;
+import android.view.WindowManager;
 
 import com.android.systemui.SystemUI;
 import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -61,7 +62,8 @@
             }
         };
         mZenModeController = zen;
-        mDialog = new VolumeDialog(context, mController, zen, mVolumeDialogCallback);
+        mDialog = new VolumeDialog(context, WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY,
+                mController, zen, mVolumeDialogCallback);
         applyConfiguration();
     }
 
@@ -76,12 +78,10 @@
         mDialog.setStreamImportant(AudioManager.STREAM_ALARM, true);
         mDialog.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
         mDialog.setShowHeaders(false);
-        mDialog.setShowFooter(true);
-        mDialog.setZenFooter(true);
         mDialog.setAutomute(true);
         mDialog.setSilentMode(false);
         mController.setVolumePolicy(mVolumePolicy);
-        mController.showDndTile(false);
+        mController.showDndTile(true);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
index 012eb41..3a8081f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
@@ -100,7 +100,7 @@
     private boolean mEnabled;
     private boolean mDestroyed;
     private VolumePolicy mVolumePolicy;
-    private boolean mShowDndTile = false;
+    private boolean mShowDndTile = true;
 
     public VolumeDialogController(Context context, ComponentName component) {
         mContext = context.getApplicationContext();
@@ -125,6 +125,10 @@
         return mAudio;
     }
 
+    public ZenModeConfig getZenModeConfig() {
+        return mNoMan.getZenModeConfig();
+    }
+
     public void dismiss() {
         mCallbacks.onDismissRequested(Events.DISMISS_REASON_VOLUME_CONTROLLER);
     }
@@ -342,7 +346,7 @@
         updateRingerModeExternalW(mAudio.getRingerMode());
         updateZenModeW();
         updateEffectsSuppressorW(mNoMan.getEffectsSuppressor());
-        updateExitConditionW();
+        updateZenModeConfigW();
         mCallbacks.onStateChanged(mState);
     }
 
@@ -395,17 +399,10 @@
         return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
     }
 
-    private Condition getExitCondition() {
-        final ZenModeConfig config = mNoMan.getZenModeConfig();
-        return config == null ? null
-                : config.manualRule == null ? null
-                : config.manualRule.condition;
-    }
-
-    private boolean updateExitConditionW() {
-        final Condition exitCondition = getExitCondition();
-        if (Objects.equals(mState.exitCondition, exitCondition)) return false;
-        mState.exitCondition = exitCondition;
+    private boolean updateZenModeConfigW() {
+        final ZenModeConfig zenModeConfig = getZenModeConfig();
+        if (Objects.equals(mState.zenModeConfig, zenModeConfig)) return false;
+        mState.zenModeConfig = zenModeConfig;
         return true;
     }
 
@@ -750,7 +747,7 @@
                 changed = updateZenModeW();
             }
             if (ZEN_MODE_CONFIG_URI.equals(uri)) {
-                changed = updateExitConditionW();
+                changed = updateZenModeConfigW();
             }
             if (changed) {
                 mCallbacks.onStateChanged(mState);
@@ -943,7 +940,7 @@
         public int zenMode;
         public ComponentName effectsSuppressor;
         public String effectsSuppressorName;
-        public Condition exitCondition;
+        public ZenModeConfig zenModeConfig;
         public int activeStream = NO_ACTIVE_STREAM;
 
         public State copy() {
@@ -956,7 +953,7 @@
             rt.zenMode = zenMode;
             if (effectsSuppressor != null) rt.effectsSuppressor = effectsSuppressor.clone();
             rt.effectsSuppressorName = effectsSuppressorName;
-            if (exitCondition != null) rt.exitCondition = exitCondition.copy();
+            if (zenModeConfig != null) rt.zenModeConfig = zenModeConfig.copy();
             rt.activeStream = activeStream;
             return rt;
         }
@@ -977,10 +974,15 @@
             sb.append(",zenMode:").append(zenMode);
             sb.append(",effectsSuppressor:").append(effectsSuppressor);
             sb.append(",effectsSuppressorName:").append(effectsSuppressorName);
-            sb.append(",exitCondition:").append(exitCondition);
+            sb.append(",zenModeConfig:").append(zenModeConfig);
             sb.append(",activeStream:").append(activeStream);
             return sb.append('}').toString();
         }
+
+        public Condition getManualExitCondition() {
+            return zenModeConfig != null && zenModeConfig.manualRule != null
+                    ? zenModeConfig.manualRule.condition : null;
+        }
     }
 
     public interface Callbacks {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
index 915e998..04339eb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
@@ -32,8 +32,6 @@
     public static final String PREF_SHOW_HEADERS = "pref_show_headers";
     public static final String PREF_SHOW_FAKE_REMOTE_1 = "pref_show_fake_remote_1";
     public static final String PREF_SHOW_FAKE_REMOTE_2 = "pref_show_fake_remote_2";
-    public static final String PREF_SHOW_FOOTER = "pref_show_footer";
-    public static final String PREF_ZEN_FOOTER = "pref_zen_footer";
     public static final String PREF_ENABLE_AUTOMUTE = "pref_enable_automute";
     public static final String PREF_ENABLE_SILENT_MODE = "pref_enable_silent_mode";
     public static final String PREF_DEBUG_LOGGING = "pref_debug_logging";
@@ -46,10 +44,8 @@
     public static final String PREF_ADJUST_NOTIFICATION = "pref_adjust_notification";
 
     public static final boolean DEFAULT_SHOW_HEADERS = true;
-    public static final boolean DEFAULT_SHOW_FOOTER = true;
     public static final boolean DEFAULT_ENABLE_AUTOMUTE = true;
     public static final boolean DEFAULT_ENABLE_SILENT_MODE = true;
-    public static final boolean DEFAULT_ZEN_FOOTER = true;
 
     public static void unregisterCallbacks(Context c, OnSharedPreferenceChangeListener listener) {
         prefs(c).unregisterOnSharedPreferenceChangeListener(listener);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 5f04aaf..2688813 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -103,7 +103,7 @@
 
     private void setDefaultVolumeController(boolean register) {
         if (register) {
-            DndTile.setVisible(mContext, false);
+            DndTile.setVisible(mContext, true);
             if (LOGD) Log.d(TAG, "Registering default volume controller");
             getVolumeComponent().register();
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 775c87d..8aded45 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -16,20 +16,12 @@
 package com.android.systemui.volume;
 
 import android.animation.LayoutTransition;
-import android.animation.ValueAnimator;
-import android.app.ActivityManager;
 import android.content.Context;
-import android.content.res.Resources;
 import android.provider.Settings.Global;
 import android.service.notification.ZenModeConfig;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
 import android.view.View;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.LinearLayout;
-import android.widget.Switch;
 import android.widget.TextView;
 
 import com.android.systemui.R;
@@ -38,70 +30,36 @@
 import java.util.Objects;
 
 /**
- * Switch bar + zen mode panel (conditions) attached to the bottom of the volume dialog.
+ * Zen mode information (and end button) attached to the bottom of the volume dialog.
  */
 public class ZenFooter extends LinearLayout {
     private static final String TAG = Util.logTag(ZenFooter.class);
 
     private final Context mContext;
-    private final float mSecondaryAlpha;
-    private final LayoutTransition mLayoutTransition;
 
-    private ZenModeController mController;
-    private Switch mSwitch;
-    private ZenModePanel mZenModePanel;
-    private View mZenModePanelButtons;
-    private View mZenModePanelMoreButton;
-    private View mZenModePanelDoneButton;
-    private View mSwitchBar;
-    private View mSwitchBarIcon;
-    private View mSummary;
     private TextView mSummaryLine1;
     private TextView mSummaryLine2;
-    private boolean mFooterExpanded;
+    private View mEndNowButton;
     private int mZen = -1;
     private ZenModeConfig mConfig;
-    private Callback mCallback;
+    private ZenModeController mController;
 
     public ZenFooter(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
-        mSecondaryAlpha = getFloat(context.getResources(), R.dimen.volume_secondary_alpha);
-        mLayoutTransition = new LayoutTransition();
-        mLayoutTransition.setDuration(new ValueAnimator().getDuration() / 2);
-        mLayoutTransition.disableTransitionType(LayoutTransition.DISAPPEARING);
-        mLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
-    }
-
-    private static float getFloat(Resources r, int resId) {
-        final TypedValue tv = new TypedValue();
-        r.getValue(resId, tv, true);
-        return tv.getFloat();
+        setLayoutTransition(new LayoutTransition());
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mSwitchBar = findViewById(R.id.volume_zen_switch_bar);
-        mSwitchBarIcon = findViewById(R.id.volume_zen_switch_bar_icon);
-        mSwitch = (Switch) findViewById(R.id.volume_zen_switch);
-        mZenModePanel = (ZenModePanel) findViewById(R.id.zen_mode_panel);
-        mZenModePanelButtons = findViewById(R.id.volume_zen_mode_panel_buttons);
-        mZenModePanelMoreButton = findViewById(R.id.volume_zen_mode_panel_more);
-        mZenModePanelDoneButton = findViewById(R.id.volume_zen_mode_panel_done);
-        mSummary = findViewById(R.id.volume_zen_panel_summary);
-        mSummaryLine1 = (TextView) findViewById(R.id.volume_zen_panel_summary_line_1);
-        mSummaryLine2 = (TextView) findViewById(R.id.volume_zen_panel_summary_line_2);
+        mSummaryLine1 = (TextView) findViewById(R.id.volume_zen_summary_line_1);
+        mSummaryLine2 = (TextView) findViewById(R.id.volume_zen_summary_line_2);
+        mEndNowButton = findViewById(R.id.volume_zen_end_now);
     }
 
-    public void init(ZenModeController controller, Callback callback) {
-        mCallback = callback;
-        mController = controller;
-        mZenModePanel.init(controller);
-        mZenModePanel.setEmbedded(true);
-        mZenModePanel.setCallback(mZenModePanelCallback);
-        mSwitch.setOnCheckedChangeListener(mCheckedListener);
-        mController.addCallback(new ZenModeController.Callback() {
+    public void init(final ZenModeController controller) {
+        controller.addCallback(new ZenModeController.Callback() {
             @Override
             public void onZenChanged(int zen) {
                 setZen(zen);
@@ -111,30 +69,15 @@
                 setConfig(config);
             }
         });
-        mSwitchBar.setOnClickListener(new OnClickListener() {
+        mEndNowButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                mSwitch.setChecked(!mSwitch.isChecked());
+                controller.setZen(Global.ZEN_MODE_OFF, null, TAG);
             }
         });
-        mZenModePanelMoreButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mCallback != null) {
-                    mCallback.onSettingsClicked();
-                }
-            }
-        });
-        mZenModePanelDoneButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mCallback != null) {
-                    mCallback.onDoneClicked();
-                }
-            }
-        });
-        mZen = mController.getZen();
-        mConfig = mController.getConfig();
+        mZen = controller.getZen();
+        mConfig = controller.getConfig();
+        mController = controller;
         update();
     }
 
@@ -166,96 +109,17 @@
         return mZen == Global.ZEN_MODE_NO_INTERRUPTIONS;
     }
 
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        setLayoutTransition(null);
-        setFooterExpanded(false);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        setLayoutTransition(mLayoutTransition);
-    }
-
-    private boolean setFooterExpanded(boolean expanded) {
-        if (mFooterExpanded == expanded) return false;
-        mFooterExpanded = expanded;
-        update();
-        if (mCallback != null) {
-            mCallback.onFooterExpanded();
-        }
-        return true;
-    }
-
-    public boolean isFooterExpanded() {
-        return mFooterExpanded;
-    }
-
     public void update() {
-        final boolean isZen = isZen();
-        mSwitch.setOnCheckedChangeListener(null);
-        mSwitch.setChecked(isZen);
-        mSwitch.setOnCheckedChangeListener(mCheckedListener);
-        Util.setVisOrGone(mZenModePanel, isZen && mFooterExpanded);
-        Util.setVisOrGone(mZenModePanelButtons, isZen && mFooterExpanded);
-        Util.setVisOrGone(mSummary, isZen && !mFooterExpanded);
-        mSwitchBarIcon.setAlpha(isZen ? 1 : mSecondaryAlpha);
         final String line1 =
                 isZenPriority() ? mContext.getString(R.string.interruption_level_priority)
                 : isZenAlarms() ? mContext.getString(R.string.interruption_level_alarms)
                 : isZenNone() ? mContext.getString(R.string.interruption_level_none)
                 : null;
         Util.setText(mSummaryLine1, line1);
+
         final String line2 = ZenModeConfig.getConditionSummary(mContext, mConfig,
-                ActivityManager.getCurrentUser());
+                mController.getCurrentUser());
         Util.setText(mSummaryLine2, line2);
     }
 
-    private final ZenModePanel.Callback mZenModePanelCallback = new ZenModePanel.Callback() {
-        @Override
-        public void onMoreSettings() {
-            if (mCallback != null) {
-                mCallback.onSettingsClicked();
-            }
-        }
-
-        @Override
-        public void onPrioritySettings() {
-            if (mCallback != null) {
-                mCallback.onPrioritySettingsClicked();
-            }
-        }
-
-        @Override
-        public void onInteraction() {
-            // noop
-        }
-
-        @Override
-        public void onExpanded(boolean expanded) {
-            // noop
-        }
-    };
-
-    private final OnCheckedChangeListener mCheckedListener = new OnCheckedChangeListener() {
-        @Override
-        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-            if (D.BUG) Log.d(TAG, "onCheckedChanged " + isChecked);
-            if (isChecked != isZen()) {
-                final int newZen = isChecked ? Global.ZEN_MODE_ALARMS : Global.ZEN_MODE_OFF;
-                mZen = newZen;  // this one's optimistic
-                setFooterExpanded(isChecked);
-                mController.setZen(newZen, null, TAG);
-            }
-        }
-    };
-
-    public interface Callback {
-        void onFooterExpanded();
-        void onSettingsClicked();
-        void onDoneClicked();
-        void onPrioritySettingsClicked();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 1b563dc..9f9c9ac 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -41,8 +41,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.ImageView;
@@ -85,22 +83,14 @@
     private final H mHandler = new H();
     private final ZenPrefs mPrefs;
     private final IconPulser mIconPulser;
-    private final int mSubheadWarningColor;
-    private final int mSubheadColor;
-    private final Interpolator mInterpolator;
     private final TransitionHelper mTransitionHelper = new TransitionHelper();
     private final Uri mForeverId;
 
     private String mTag = TAG + "/" + Integer.toHexString(System.identityHashCode(this));
 
     private SegmentedButtons mZenButtons;
-    private ViewGroup mZenButtonsContainer;
-    private View mZenSubhead;
-    private TextView mZenSubheadCollapsed;
-    private TextView mZenSubheadExpanded;
-    private View mZenEmbeddedDivider;
-    private View mMoreSettings;
     private View mZenIntroduction;
+    private TextView mZenIntroductionMessage;
     private View mZenIntroductionConfirm;
     private View mZenIntroductionCustomize;
     private LinearLayout mZenConditions;
@@ -113,7 +103,6 @@
     private int mFirstConditionIndex;
     private boolean mRequestingConditions;
     private Condition mExitCondition;
-    private String mExitConditionText;
     private int mBucketIndex = -1;
     private boolean mExpanded;
     private boolean mHidden;
@@ -123,7 +112,6 @@
     private Condition mSessionExitCondition;
     private Condition[] mConditions;
     private Condition mTimeCondition;
-    private boolean mEmbedded;
 
     public ZenModePanel(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -131,10 +119,6 @@
         mPrefs = new ZenPrefs();
         mInflater = LayoutInflater.from(mContext.getApplicationContext());
         mIconPulser = new IconPulser(mContext);
-        mSubheadWarningColor = context.getColor(R.color.system_warning_color);
-        mSubheadColor = context.getColor(R.color.qs_subhead);
-        mInterpolator = AnimationUtils.loadInterpolator(mContext,
-                com.android.internal.R.interpolator.fast_out_slow_in);
         mForeverId = Condition.newId(mContext).appendPath("forever").build();
         if (DEBUG) Log.d(mTag, "new ZenModePanel");
     }
@@ -149,25 +133,13 @@
         pw.print("  mExpanded="); pw.println(mExpanded);
         pw.print("  mSessionZen="); pw.println(mSessionZen);
         pw.print("  mAttachedZen="); pw.println(mAttachedZen);
-        pw.print("  mEmbedded="); pw.println(mEmbedded);
+        pw.print("  mConfirmedPriorityIntroduction=");
+        pw.println(mPrefs.mConfirmedPriorityIntroduction);
+        pw.print("  mConfirmedSilenceIntroduction=");
+        pw.println(mPrefs.mConfirmedSilenceIntroduction);
         mTransitionHelper.dump(fd, pw, args);
     }
 
-    public void setEmbedded(boolean embedded) {
-        if (mEmbedded == embedded) return;
-        mEmbedded = embedded;
-        mZenButtonsContainer.setLayoutTransition(mEmbedded ? null : newLayoutTransition(null));
-        setLayoutTransition(mEmbedded ? null : newLayoutTransition(null));
-        if (mEmbedded) {
-            mZenButtonsContainer.setBackground(null);
-        } else {
-            mZenButtonsContainer.setBackgroundResource(R.drawable.qs_background_secondary);
-        }
-        mZenButtons.getChildAt(3).setVisibility(mEmbedded ? GONE : VISIBLE);
-        mZenEmbeddedDivider.setVisibility(mEmbedded ? VISIBLE : GONE);
-        updateWidgets();
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -179,37 +151,10 @@
                 Global.ZEN_MODE_ALARMS);
         mZenButtons.addButton(R.string.interruption_level_priority_twoline,
                 Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        mZenButtons.addButton(R.string.interruption_level_all, Global.ZEN_MODE_OFF);
         mZenButtons.setCallback(mZenButtonsCallback);
 
-        mZenButtonsContainer = (ViewGroup) findViewById(R.id.zen_buttons_container);
-        mZenButtonsContainer.setLayoutTransition(newLayoutTransition(null));
-
-        mZenSubhead = findViewById(R.id.zen_subhead);
-        mZenEmbeddedDivider = findViewById(R.id.zen_embedded_divider);
-
-        mZenSubheadCollapsed = (TextView) findViewById(R.id.zen_subhead_collapsed);
-        mZenSubheadCollapsed.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                setExpanded(true);
-            }
-        });
-        Interaction.register(mZenSubheadCollapsed, mInteractionCallback);
-
-        mZenSubheadExpanded = (TextView) findViewById(R.id.zen_subhead_expanded);
-        Interaction.register(mZenSubheadExpanded, mInteractionCallback);
-
-        mMoreSettings = findViewById(R.id.zen_more_settings);
-        mMoreSettings.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                fireMoreSettings();
-            }
-        });
-        Interaction.register(mMoreSettings, mInteractionCallback);
-
         mZenIntroduction = findViewById(R.id.zen_introduction);
+        mZenIntroductionMessage = (TextView) findViewById(R.id.zen_introduction_message);
         mZenIntroductionConfirm = findViewById(R.id.zen_introduction_confirm);
         mZenIntroductionConfirm.setOnClickListener(new OnClickListener() {
             @Override
@@ -230,25 +175,25 @@
 
         mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
 
-        setLayoutTransition(newLayoutTransition(mTransitionHelper));
     }
 
     private void confirmZenIntroduction() {
-        if (DEBUG) Log.d(TAG, "confirmZenIntroduction");
-        Prefs.putBoolean(mContext, Prefs.Key.DND_CONFIRMED_PRIORITY_INTRODUCTION, true);
+        final String prefKey = prefKeyForConfirmation(getSelectedZen(Global.ZEN_MODE_OFF));
+        if (prefKey == null) return;
+        if (DEBUG) Log.d(TAG, "confirmZenIntroduction " + prefKey);
+        Prefs.putBoolean(mContext, prefKey, true);
         mHandler.sendEmptyMessage(H.UPDATE_WIDGETS);
     }
 
-    private LayoutTransition newLayoutTransition(TransitionListener listener) {
-        final LayoutTransition transition = new LayoutTransition();
-        transition.disableTransitionType(LayoutTransition.DISAPPEARING);
-        transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
-        transition.disableTransitionType(LayoutTransition.APPEARING);
-        transition.setInterpolator(LayoutTransition.CHANGE_APPEARING, mInterpolator);
-        if (listener != null) {
-            transition.addTransitionListener(listener);
+    private static String prefKeyForConfirmation(int zen) {
+        switch (zen) {
+            case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+                return Prefs.Key.DND_CONFIRMED_PRIORITY_INTRODUCTION;
+            case Global.ZEN_MODE_NO_INTERRUPTIONS:
+                return Prefs.Key.DND_CONFIRMED_SILENCE_INTRODUCTION;
+            default:
+                return null;
         }
-        return transition;
     }
 
     @Override
@@ -260,7 +205,6 @@
         mSessionZen = mAttachedZen;
         mTransitionHelper.clear();
         setSessionExitCondition(copy(mExitCondition));
-        refreshExitConditionText();
         updateWidgets();
         setRequestingConditions(!mHidden);
     }
@@ -274,9 +218,6 @@
         mAttachedZen = -1;
         mSessionZen = -1;
         setSessionExitCondition(null);
-        if (!mEmbedded) {
-            setExpanded(false);
-        }
         setRequestingConditions(false);
         mTransitionHelper.clear();
     }
@@ -359,7 +300,6 @@
         for (int i = 0; i < mMaxConditions; i++) {
             mZenConditions.addView(mInflater.inflate(R.layout.zen_mode_condition, this, false));
         }
-        refreshExitConditionText();
         mSessionZen = getSelectedZen(-1);
         handleUpdateManualRule(mController.getManualRule());
         if (DEBUG) Log.d(mTag, "init mExitCondition=" + mExitCondition);
@@ -375,7 +315,6 @@
         if (Objects.equals(mExitCondition, exitCondition)) return;
         mExitCondition = exitCondition;
         if (DEBUG) Log.d(mTag, "mExitCondition=" + getConditionId(mExitCondition));
-        refreshExitConditionText();
         updateWidgets();
     }
 
@@ -395,10 +334,6 @@
         return condition == null ? null : condition.copy();
     }
 
-    private void refreshExitConditionText() {
-        mExitConditionText = getExitConditionText(mContext, mExitCondition);
-    }
-
     public static String getExitConditionText(Context context, Condition exitCondition) {
         if (exitCondition == null) {
             return foreverSummary(context);
@@ -430,7 +365,7 @@
 
     private void handleUpdateZen(int zen) {
         if (mSessionZen != -1 && mSessionZen != zen) {
-            setExpanded(mEmbedded && isShown() || !mEmbedded && zen != Global.ZEN_MODE_OFF);
+            setExpanded(isShown());
             mSessionZen = zen;
         }
         mZenButtons.setSelectedValue(zen);
@@ -480,30 +415,18 @@
             return;
         }
         final int zen = getSelectedZen(Global.ZEN_MODE_OFF);
-        final boolean zenOff = zen == Global.ZEN_MODE_OFF;
         final boolean zenImportant = zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
-        final boolean expanded = !mHidden && mExpanded;
-        final boolean conditions = mEmbedded || !zenOff && expanded;
-        final boolean introduction = conditions && zenImportant && !mPrefs.mConfirmedIntroduction;
+        final boolean introduction = (zenImportant && !mPrefs.mConfirmedPriorityIntroduction
+                        || zenNone && !mPrefs.mConfirmedSilenceIntroduction);
 
         mZenButtons.setVisibility(mHidden ? GONE : VISIBLE);
-        mZenSubhead.setVisibility(!mHidden && !zenOff && !mEmbedded ? VISIBLE : GONE);
-        mZenSubheadExpanded.setVisibility(expanded ? VISIBLE : GONE);
-        mZenSubheadCollapsed.setVisibility(!expanded ? VISIBLE : GONE);
-        mMoreSettings.setVisibility(zenImportant && expanded ? VISIBLE : GONE);
-        mZenConditions.setVisibility(conditions ? VISIBLE : GONE);
-
-        if (zenNone) {
-            mZenSubheadExpanded.setText(R.string.zen_no_interruptions_with_warning);
-            mZenSubheadCollapsed.setText(mExitConditionText);
-        } else if (zenImportant) {
-            mZenSubheadExpanded.setText(R.string.zen_important_interruptions);
-            mZenSubheadCollapsed.setText(mExitConditionText);
-        }
-        mZenSubheadExpanded.setTextColor(zenNone && mPrefs.isNoneDangerous()
-                ? mSubheadWarningColor : mSubheadColor);
         mZenIntroduction.setVisibility(introduction ? VISIBLE : GONE);
+        if (introduction) {
+            mZenIntroductionMessage.setText(zenImportant ? R.string.zen_priority_introduction
+                    : R.string.zen_silence_introduction);
+            mZenIntroductionCustomize.setVisibility(zenImportant ? VISIBLE : GONE);
+        }
     }
 
     private static Condition parseExistingTimeCondition(Context context, Condition condition) {
@@ -761,13 +684,13 @@
         String modeText;
         switch(zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
-                modeText = mContext.getString(R.string.zen_important_interruptions);
+                modeText = mContext.getString(R.string.interruption_level_priority);
                 break;
             case Global.ZEN_MODE_NO_INTERRUPTIONS:
-                modeText = mContext.getString(R.string.zen_no_interruptions);
+                modeText = mContext.getString(R.string.interruption_level_none);
                 break;
             case Global.ZEN_MODE_ALARMS:
-                modeText = mContext.getString(R.string.zen_alarms);
+                modeText = mContext.getString(R.string.interruption_level_alarms);
                 break;
             default:
                 return;
@@ -837,12 +760,6 @@
         setSessionExitCondition(copy(condition));
     }
 
-    private void fireMoreSettings() {
-        if (mCallback != null) {
-            mCallback.onMoreSettings();
-        }
-    }
-
     private void fireInteraction() {
         if (mCallback != null) {
             mCallback.onInteraction();
@@ -887,7 +804,6 @@
     }
 
     public interface Callback {
-        void onMoreSettings();
         void onPrioritySettings();
         void onInteraction();
         void onExpanded(boolean expanded);
@@ -907,7 +823,8 @@
 
         private int mMinuteIndex;
         private int mNoneSelected;
-        private boolean mConfirmedIntroduction;
+        private boolean mConfirmedPriorityIntroduction;
+        private boolean mConfirmedSilenceIntroduction;
 
         private ZenPrefs() {
             mNoneDangerousThreshold = mContext.getResources()
@@ -915,11 +832,8 @@
             Prefs.registerListener(mContext, this);
             updateMinuteIndex();
             updateNoneSelected();
-            updateConfirmedIntroduction();
-        }
-
-        public boolean isNoneDangerous() {
-            return mNoneSelected < mNoneDangerousThreshold;
+            updateConfirmedPriorityIntroduction();
+            updateConfirmedSilenceIntroduction();
         }
 
         public void trackNoneSelected() {
@@ -945,7 +859,8 @@
         public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
             updateMinuteIndex();
             updateNoneSelected();
-            updateConfirmedIntroduction();
+            updateConfirmedPriorityIntroduction();
+            updateConfirmedSilenceIntroduction();
         }
 
         private void updateMinuteIndex() {
@@ -968,12 +883,22 @@
             return MathUtils.constrain(noneSelected, 0, Integer.MAX_VALUE);
         }
 
-        private void updateConfirmedIntroduction() {
+        private void updateConfirmedPriorityIntroduction() {
             final boolean confirmed =  Prefs.getBoolean(mContext,
                     Prefs.Key.DND_CONFIRMED_PRIORITY_INTRODUCTION, false);
-            if (confirmed == mConfirmedIntroduction) return;
-            mConfirmedIntroduction = confirmed;
-            if (DEBUG) Log.d(mTag, "Confirmed introduction: " + mConfirmedIntroduction);
+            if (confirmed == mConfirmedPriorityIntroduction) return;
+            mConfirmedPriorityIntroduction = confirmed;
+            if (DEBUG) Log.d(mTag, "Confirmed priority introduction: "
+                    + mConfirmedPriorityIntroduction);
+        }
+
+        private void updateConfirmedSilenceIntroduction() {
+            final boolean confirmed =  Prefs.getBoolean(mContext,
+                    Prefs.Key.DND_CONFIRMED_SILENCE_INTRODUCTION, false);
+            if (confirmed == mConfirmedSilenceIntroduction) return;
+            mConfirmedSilenceIntroduction = confirmed;
+            if (DEBUG) Log.d(mTag, "Confirmed silence introduction: "
+                    + mConfirmedSilenceIntroduction);
         }
     }
 
@@ -981,12 +906,16 @@
         @Override
         public void onSelected(final Object value) {
             if (value != null && mZenButtons.isShown() && isAttachedToWindow()) {
-                if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + value);
+                final int zen = (Integer) value;
+                if (DEBUG) Log.d(mTag, "mZenButtonsCallback selected=" + zen);
                 final Uri realConditionId = getRealConditionId(mSessionExitCondition);
                 AsyncTask.execute(new Runnable() {
                     @Override
                     public void run() {
-                        mController.setZen((Integer) value, realConditionId, TAG + ".selectZen");
+                        mController.setZen(zen, realConditionId, TAG + ".selectZen");
+                        if (zen != Global.ZEN_MODE_OFF) {
+                            Prefs.putInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, zen);
+                        }
                     }
                 });
             }
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index abd2ca0..ef9d0c3 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -180,6 +180,11 @@
 34001 device_idle_step
 34002 device_idle_wake_from_idle (is_idle|1|5), (reason|3)
 
+# ---------------------------
+# DisplayManagerService.java
+# ---------------------------
+# Auto-brightness adjustments by the user.
+35000 auto_brightness_adj (old_adj|5),(old_lux|5),(old_brightness|5),(old_gamma|5),(new_adj|5),(new_lux|5),(new_brightness|5),(new_gamma|5)
 
 # ---------------------------
 # ConnectivityService.java
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 7172ab7..74adeb7 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -62,11 +62,11 @@
 import android.os.storage.StorageResultCode;
 import android.os.storage.StorageVolume;
 import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
-import android.util.DebugUtils;
 import android.util.Log;
 import android.util.Slog;
 import android.util.Xml;
@@ -251,49 +251,7 @@
     private static final String ATTR_NICKNAME = "nickname";
     private static final String ATTR_USER_FLAGS = "userFlags";
 
-    private final AtomicFile mMetadataFile;
-
-    private static class VolumeMetadata {
-        public final int type;
-        public final String fsUuid;
-        public String nickname;
-        public int userFlags;
-
-        public VolumeMetadata(int type, String fsUuid) {
-            this.type = type;
-            this.fsUuid = Preconditions.checkNotNull(fsUuid);
-        }
-
-        public static VolumeMetadata read(XmlPullParser in) throws IOException {
-            final int type = readIntAttribute(in, ATTR_TYPE);
-            final String fsUuid = readStringAttribute(in, ATTR_FS_UUID);
-            final VolumeMetadata meta = new VolumeMetadata(type, fsUuid);
-            meta.nickname = readStringAttribute(in, ATTR_NICKNAME);
-            meta.userFlags = readIntAttribute(in, ATTR_USER_FLAGS);
-            return meta;
-        }
-
-        public static void write(XmlSerializer out, VolumeMetadata meta) throws IOException {
-            out.startTag(null, TAG_VOLUME);
-            writeIntAttribute(out, ATTR_TYPE, meta.type);
-            writeStringAttribute(out, ATTR_FS_UUID, meta.fsUuid);
-            writeStringAttribute(out, ATTR_NICKNAME, meta.nickname);
-            writeIntAttribute(out, ATTR_USER_FLAGS, meta.userFlags);
-            out.endTag(null, TAG_VOLUME);
-        }
-
-        public void dump(IndentingPrintWriter pw) {
-            pw.println("VolumeMetadata:");
-            pw.increaseIndent();
-            pw.printPair("type", DebugUtils.valueToString(VolumeInfo.class, "TYPE_", type));
-            pw.printPair("fsUuid", fsUuid);
-            pw.printPair("nickname", nickname);
-            pw.printPair("userFlags",
-                    DebugUtils.flagsToString(VolumeInfo.class, "USER_FLAG_", userFlags));
-            pw.decreaseIndent();
-            pw.println();
-        }
-    }
+    private final AtomicFile mSettingsFile;
 
     /**
      * <em>Never</em> hold the lock while performing downcalls into vold, since
@@ -311,9 +269,9 @@
     @GuardedBy("mLock")
     private ArrayMap<String, VolumeInfo> mVolumes = new ArrayMap<>();
 
-    /** Map from UUID to metadata */
+    /** Map from UUID to record */
     @GuardedBy("mLock")
-    private ArrayMap<String, VolumeMetadata> mMetadata = new ArrayMap<>();
+    private ArrayMap<String, VolumeRecord> mRecords = new ArrayMap<>();
     @GuardedBy("mLock")
     private String mPrimaryStorageUuid;
 
@@ -370,15 +328,6 @@
         }
     }
 
-    private VolumeMetadata findOrCreateMetadataLocked(VolumeInfo vol) {
-        VolumeMetadata meta = mMetadata.get(vol.fsUuid);
-        if (meta == null) {
-            meta = new VolumeMetadata(vol.type, vol.fsUuid);
-            mMetadata.put(meta.fsUuid, meta);
-        }
-        return meta;
-    }
-
     private CountDownLatch findOrCreateDiskScanLatch(String diskId) {
         synchronized (mLock) {
             CountDownLatch latch = mDiskScanLatches.get(diskId);
@@ -580,7 +529,9 @@
                 case H_FSTRIM: {
                     if (!isReady()) {
                         Slog.i(TAG, "fstrim requested, but no daemon connection yet; trying again");
-                        sendMessageDelayed(obtainMessage(H_FSTRIM), DateUtils.SECOND_IN_MILLIS);
+                        sendMessageDelayed(obtainMessage(H_FSTRIM, msg.obj),
+                                DateUtils.SECOND_IN_MILLIS);
+                        break;
                     }
 
                     Slog.i(TAG, "Running fstrim idle maintenance");
@@ -911,7 +862,7 @@
                     final int oldState = vol.state;
                     final int newState = Integer.parseInt(cooked[2]);
                     vol.state = newState;
-                    onVolumeStateChangedLocked(vol.clone(), oldState, newState);
+                    onVolumeStateChangedLocked(vol, oldState, newState);
                 }
                 break;
             }
@@ -921,7 +872,6 @@
                 if (vol != null) {
                     vol.fsType = cooked[2];
                 }
-                mCallbacks.notifyVolumeMetadataChanged(vol.clone());
                 break;
             }
             case VoldResponseCode.VOLUME_FS_UUID_CHANGED: {
@@ -930,8 +880,6 @@
                 if (vol != null) {
                     vol.fsUuid = cooked[2];
                 }
-                refreshMetadataLocked();
-                mCallbacks.notifyVolumeMetadataChanged(vol.clone());
                 break;
             }
             case VoldResponseCode.VOLUME_FS_LABEL_CHANGED: {
@@ -943,7 +891,7 @@
                     }
                     vol.fsLabel = builder.toString().trim();
                 }
-                mCallbacks.notifyVolumeMetadataChanged(vol.clone());
+                // TODO: notify listeners that label changed
                 break;
             }
             case VoldResponseCode.VOLUME_PATH_CHANGED: {
@@ -1068,6 +1016,19 @@
     }
 
     private void onVolumeStateChangedLocked(VolumeInfo vol, int oldState, int newState) {
+        // Remember that we saw this volume so we're ready to accept user
+        // metadata, or so we can annoy them when a private volume is ejected
+        if (vol.isMountedReadable() && !TextUtils.isEmpty(vol.fsUuid)) {
+            if (!mRecords.containsKey(vol.fsUuid)) {
+                final VolumeRecord rec = new VolumeRecord(vol.type, vol.fsUuid);
+                if (vol.type == VolumeInfo.TYPE_PRIVATE) {
+                    rec.nickname = vol.disk.getDescription();
+                }
+                mRecords.put(rec.fsUuid, rec);
+                writeSettingsLocked();
+            }
+        }
+
         mCallbacks.notifyVolumeStateChanged(vol, oldState, newState);
 
         if (isBroadcastWorthy(vol)) {
@@ -1115,7 +1076,7 @@
 
         // TODO: estimate remaining time
         try {
-            mMoveCallback.onStatusChanged(-1, status, -1);
+            mMoveCallback.onStatusChanged(-1, null, status, -1);
         } catch (RemoteException ignored) {
         }
 
@@ -1125,7 +1086,7 @@
             Slog.d(TAG, "Move to " + mMoveTargetUuid + " copy phase finshed; persisting");
 
             mPrimaryStorageUuid = mMoveTargetUuid;
-            writeMetadataLocked();
+            writeSettingsLocked();
         }
 
         if (PackageManager.isMoveStatusFinished(status)) {
@@ -1136,25 +1097,6 @@
         }
     }
 
-    /**
-     * Refresh latest metadata into any currently active {@link VolumeInfo}.
-     */
-    private void refreshMetadataLocked() {
-        final int size = mVolumes.size();
-        for (int i = 0; i < size; i++) {
-            final VolumeInfo vol = mVolumes.valueAt(i);
-            final VolumeMetadata meta = mMetadata.get(vol.fsUuid);
-
-            if (meta != null) {
-                vol.nickname = meta.nickname;
-                vol.userFlags = meta.userFlags;
-            } else {
-                vol.nickname = null;
-                vol.userFlags = 0;
-            }
-        }
-    }
-
     private void enforcePermission(String perm) {
         mContext.enforceCallingOrSelfPermission(perm, perm);
     }
@@ -1203,11 +1145,11 @@
             mLastMaintenance = mLastMaintenanceFile.lastModified();
         }
 
-        mMetadataFile = new AtomicFile(
+        mSettingsFile = new AtomicFile(
                 new File(Environment.getSystemSecureDirectory(), "storage.xml"));
 
         synchronized (mLock) {
-            readMetadataLocked();
+            readSettingsLocked();
         }
 
         /*
@@ -1233,12 +1175,12 @@
         mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
     }
 
-    private void readMetadataLocked() {
-        mMetadata.clear();
+    private void readSettingsLocked() {
+        mRecords.clear();
 
         FileInputStream fis = null;
         try {
-            fis = mMetadataFile.openRead();
+            fis = mSettingsFile.openRead();
             final XmlPullParser in = Xml.newPullParser();
             in.setInput(fis, null);
 
@@ -1261,8 +1203,8 @@
                         }
 
                     } else if (TAG_VOLUME.equals(tag)) {
-                        final VolumeMetadata meta = VolumeMetadata.read(in);
-                        mMetadata.put(meta.fsUuid, meta);
+                        final VolumeRecord rec = readVolumeRecord(in);
+                        mRecords.put(rec.fsUuid, rec);
                     }
                 }
             }
@@ -1277,10 +1219,10 @@
         }
     }
 
-    private void writeMetadataLocked() {
+    private void writeSettingsLocked() {
         FileOutputStream fos = null;
         try {
-            fos = mMetadataFile.startWrite();
+            fos = mSettingsFile.startWrite();
 
             XmlSerializer out = new FastXmlSerializer();
             out.setOutput(fos, "utf-8");
@@ -1288,22 +1230,40 @@
             out.startTag(null, TAG_VOLUMES);
             writeIntAttribute(out, ATTR_VERSION, VERSION_ADD_PRIMARY);
             writeStringAttribute(out, ATTR_PRIMARY_STORAGE_UUID, mPrimaryStorageUuid);
-            final int size = mMetadata.size();
+            final int size = mRecords.size();
             for (int i = 0; i < size; i++) {
-                final VolumeMetadata meta = mMetadata.valueAt(i);
-                VolumeMetadata.write(out, meta);
+                final VolumeRecord rec = mRecords.valueAt(i);
+                writeVolumeRecord(out, rec);
             }
             out.endTag(null, TAG_VOLUMES);
             out.endDocument();
 
-            mMetadataFile.finishWrite(fos);
+            mSettingsFile.finishWrite(fos);
         } catch (IOException e) {
             if (fos != null) {
-                mMetadataFile.failWrite(fos);
+                mSettingsFile.failWrite(fos);
             }
         }
     }
 
+    public static VolumeRecord readVolumeRecord(XmlPullParser in) throws IOException {
+        final int type = readIntAttribute(in, ATTR_TYPE);
+        final String fsUuid = readStringAttribute(in, ATTR_FS_UUID);
+        final VolumeRecord meta = new VolumeRecord(type, fsUuid);
+        meta.nickname = readStringAttribute(in, ATTR_NICKNAME);
+        meta.userFlags = readIntAttribute(in, ATTR_USER_FLAGS);
+        return meta;
+    }
+
+    public static void writeVolumeRecord(XmlSerializer out, VolumeRecord rec) throws IOException {
+        out.startTag(null, TAG_VOLUME);
+        writeIntAttribute(out, ATTR_TYPE, rec.type);
+        writeStringAttribute(out, ATTR_FS_UUID, rec.fsUuid);
+        writeStringAttribute(out, ATTR_NICKNAME, rec.nickname);
+        writeIntAttribute(out, ATTR_USER_FLAGS, rec.userFlags);
+        out.endTag(null, TAG_VOLUME);
+    }
+
     /**
      * Exposed API calls below here
      */
@@ -1469,32 +1429,40 @@
     }
 
     @Override
-    public void setVolumeNickname(String volId, String nickname) {
+    public void setVolumeNickname(String fsUuid, String nickname) {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
 
         synchronized (mLock) {
-            final VolumeInfo vol = findVolumeById(volId);
-            final VolumeMetadata meta = findOrCreateMetadataLocked(vol);
-            meta.nickname = nickname;
-            refreshMetadataLocked();
-            writeMetadataLocked();
-            mCallbacks.notifyVolumeMetadataChanged(vol.clone());
+            final VolumeRecord rec = mRecords.get(fsUuid);
+            rec.nickname = nickname;
+            mCallbacks.notifyVolumeMetadataChanged(fsUuid);
+            writeSettingsLocked();
         }
     }
 
     @Override
-    public void setVolumeUserFlags(String volId, int flags, int mask) {
+    public void setVolumeUserFlags(String fsUuid, int flags, int mask) {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
 
         synchronized (mLock) {
-            final VolumeInfo vol = findVolumeById(volId);
-            final VolumeMetadata meta = findOrCreateMetadataLocked(vol);
-            meta.userFlags = (meta.userFlags & ~mask) | (flags & mask);
-            refreshMetadataLocked();
-            writeMetadataLocked();
-            mCallbacks.notifyVolumeMetadataChanged(vol.clone());
+            final VolumeRecord rec = mRecords.get(fsUuid);
+            rec.userFlags = (rec.userFlags & ~mask) | (flags & mask);
+            mCallbacks.notifyVolumeMetadataChanged(fsUuid);
+            writeSettingsLocked();
+        }
+    }
+
+    @Override
+    public void forgetVolume(String fsUuid) {
+        enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+        waitForReady();
+
+        synchronized (mLock) {
+            mRecords.remove(fsUuid);
+            mCallbacks.notifyVolumeMetadataChanged(fsUuid);
+            writeSettingsLocked();
         }
     }
 
@@ -2327,11 +2295,6 @@
 
     @Override
     public VolumeInfo[] getVolumes(int flags) {
-        if ((flags & StorageManager.FLAG_ALL_METADATA) != 0) {
-            // TODO: implement support for returning all metadata
-            throw new UnsupportedOperationException();
-        }
-
         synchronized (mLock) {
             final VolumeInfo[] res = new VolumeInfo[mVolumes.size()];
             for (int i = 0; i < mVolumes.size(); i++) {
@@ -2341,6 +2304,17 @@
         }
     }
 
+    @Override
+    public VolumeRecord[] getVolumeRecords(int flags) {
+        synchronized (mLock) {
+            final VolumeRecord[] res = new VolumeRecord[mRecords.size()];
+            for (int i = 0; i < mRecords.size(); i++) {
+                res[i] = mRecords.valueAt(i);
+            }
+            return res;
+        }
+    }
+
     private void addObbStateLocked(ObbState obbState) throws RemoteException {
         final IBinder binder = obbState.getBinder();
         List<ObbState> obbStates = mObbMounts.get(binder);
@@ -2890,7 +2864,7 @@
                     break;
                 }
                 case MSG_VOLUME_METADATA_CHANGED: {
-                    callback.onVolumeMetadataChanged((VolumeInfo) args.arg1);
+                    callback.onVolumeMetadataChanged((String) args.arg1);
                     break;
                 }
                 case MSG_DISK_SCANNED: {
@@ -2910,21 +2884,21 @@
 
         private void notifyVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
             final SomeArgs args = SomeArgs.obtain();
-            args.arg1 = vol;
+            args.arg1 = vol.clone();
             args.argi2 = oldState;
             args.argi3 = newState;
             obtainMessage(MSG_VOLUME_STATE_CHANGED, args).sendToTarget();
         }
 
-        private void notifyVolumeMetadataChanged(VolumeInfo vol) {
+        private void notifyVolumeMetadataChanged(String fsUuid) {
             final SomeArgs args = SomeArgs.obtain();
-            args.arg1 = vol;
+            args.arg1 = fsUuid;
             obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget();
         }
 
         private void notifyDiskScanned(DiskInfo disk, int volumeCount) {
             final SomeArgs args = SomeArgs.obtain();
-            args.arg1 = disk;
+            args.arg1 = disk.clone();
             args.argi2 = volumeCount;
             obtainMessage(MSG_DISK_SCANNED, args).sendToTarget();
         }
@@ -2935,10 +2909,10 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
 
         for (String arg : args) {
-            if ("--clear-metadata".equals(arg)) {
+            if ("--clear".equals(arg)) {
                 synchronized (mLock) {
-                    mMetadata.clear();
-                    writeMetadataLocked();
+                    mRecords.clear();
+                    writeSettingsLocked();
                 }
             }
         }
@@ -2964,11 +2938,11 @@
             pw.decreaseIndent();
 
             pw.println();
-            pw.println("Metadata:");
+            pw.println("Records:");
             pw.increaseIndent();
-            for (int i = 0; i < mMetadata.size(); i++) {
-                final VolumeMetadata meta = mMetadata.valueAt(i);
-                meta.dump(pw);
+            for (int i = 0; i < mRecords.size(); i++) {
+                final VolumeRecord note = mRecords.valueAt(i);
+                note.dump(pw);
             }
             pw.decreaseIndent();
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 4ee6657..8c6e290 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -759,47 +759,50 @@
     }
 
     public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) {
-        log("notifySignalStrengthForSubscriber: subId=" + subId
-                + " signalStrength=" + signalStrength);
         if (!checkNotifyPermission("notifySignalStrength()")) {
-            log("notifySignalStrengthForSubscriber: permission check failure");
             return;
         }
-        toStringLogSSC("notifySignalStrengthForSubscriber");
+        if (VDBG) {
+            log("notifySignalStrengthForSubscriber: subId=" + subId
+                + " signalStrength=" + signalStrength);
+            toStringLogSSC("notifySignalStrengthForSubscriber");
+        }
         synchronized (mRecords) {
             int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
-                log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
+                if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
                 mSignalStrength[phoneId] = signalStrength;
                 for (Record r : mRecords) {
-                    log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
-                            + " phoneId=" + phoneId + " ss=" + signalStrength);
+                    if (VDBG) {
+                        log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
+                                + " phoneId=" + phoneId + " ss=" + signalStrength);
+                    }
                     if (r.matchPhoneStateListenerEvent(
                                 PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
                             idMatch(r.subId, subId, phoneId)) {
                         try {
-                            log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
-                                    + " subId=" + subId + " phoneId=" + phoneId
-                                    + " ss=" + signalStrength);
+                            if (DBG) {
+                                log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
+                                        + " subId=" + subId + " phoneId=" + phoneId
+                                        + " ss=" + signalStrength);
+                            }
                             r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
                         } catch (RemoteException ex) {
-                            log("notifySignalStrengthForSubscriber: Exception while calling callback!!");
                             mRemoveList.add(r.binder);
                         }
-                    } else {
-                        log("notifySignalStrengthForSubscriber: no match for LISTEN_SIGNAL_STRENGTHS");
                     }
                     if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
                             idMatch(r.subId, subId, phoneId)){
                         try {
                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
-                            log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
-                                    + " subId=" + subId + " phoneId=" + phoneId
-                                    + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
+                            if (DBG) {
+                                log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
+                                        + " subId=" + subId + " phoneId=" + phoneId
+                                        + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
+                            }
                             r.callback.onSignalStrengthChanged(ss);
                         } catch (RemoteException ex) {
-                            log("notifySignalStrengthForSubscriber: Exception in deprecated LISTEN_SIGNAL_STRENGTH");
                             mRemoveList.add(r.binder);
                         }
                     }
@@ -807,7 +810,6 @@
             } else {
                 log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId);
             }
-            log("notifySignalStrengthForSubscriber: done with all records");
             handleRemoveListLocked();
         }
         broadcastSignalStrengthChanged(signalStrength, subId);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 999e91b..ac2f5b0 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -54,6 +54,7 @@
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteStatement;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -83,9 +84,12 @@
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -109,7 +113,9 @@
 
     private static final int TIMEOUT_DELAY_MS = 1000 * 60;
     private static final String DATABASE_NAME = "accounts.db";
-    private static final int DATABASE_VERSION = 7;
+    private static final int DATABASE_VERSION = 8;
+
+    private static final int MAX_DEBUG_DB_SIZE = 64;
 
     private final Context mContext;
 
@@ -214,6 +220,9 @@
         private final HashMap<Account, AtomicReference<String>> previousNameCache =
                 new HashMap<Account, AtomicReference<String>>();
 
+        private int debugDbInsertionPoint = -1;
+        private SQLiteStatement statementForLogging;
+
         UserAccounts(Context context, int userId) {
             this.userId = userId;
             synchronized (cacheLock) {
@@ -320,6 +329,8 @@
         UserAccounts accounts = mUsers.get(userId);
         if (accounts == null) {
             accounts = new UserAccounts(mContext, userId);
+            initializeDebugDbSizeAndCompileSqlStatementForLogging(
+                    accounts.openHelper.getWritableDatabase(), accounts);
             mUsers.append(userId, accounts);
             purgeOldGrants(accounts);
             validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
@@ -407,6 +418,10 @@
                                 + accountType + " no longer has a registered authenticator");
                         db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
                         accountDeleted = true;
+
+                        logRecord(db, DebugDbHelper.ACTION_AUTHENTICATOR_REMOVE, TABLE_ACCOUNTS,
+                                accountId, accounts);
+
                         final Account account = new Account(accountName, accountType);
                         accounts.userDataCache.remove(account);
                         accounts.authTokenCache.remove(account);
@@ -666,9 +681,10 @@
 
         UserAccounts accounts = getUserAccountsForCaller();
         // fails if the account already exists
+        int uid = getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
-            return addAccountInternal(accounts, account, password, extras, false);
+            return addAccountInternal(accounts, account, password, extras, false, uid);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -811,7 +827,7 @@
     }
 
     private boolean addAccountInternal(UserAccounts accounts, Account account, String password,
-            Bundle extras, boolean restricted) {
+            Bundle extras, boolean restricted, int callingUid) {
         if (account == null) {
             return false;
         }
@@ -850,6 +866,10 @@
                     }
                 }
                 db.setTransactionSuccessful();
+
+                logRecord(db, DebugDbHelper.ACTION_ACCOUNT_ADD, TABLE_ACCOUNTS, accountId,
+                        accounts, callingUid);
+
                 insertAccountIntoCacheLocked(accounts, account);
             } finally {
                 db.endTransaction();
@@ -983,9 +1003,12 @@
         if (accountToRename == null) throw new IllegalArgumentException("account is null");
         checkAuthenticateAccountsPermission(accountToRename);
         UserAccounts accounts = getUserAccountsForCaller();
+
+        int callingUid = getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
-            Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName);
+            Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName,
+                    callingUid);
             Bundle result = new Bundle();
             result.putString(AccountManager.KEY_ACCOUNT_NAME, resultingAccount.name);
             result.putString(AccountManager.KEY_ACCOUNT_TYPE, resultingAccount.type);
@@ -1000,7 +1023,7 @@
     }
 
     private Account renameAccountInternal(
-            UserAccounts accounts, Account accountToRename, String newName) {
+            UserAccounts accounts, Account accountToRename, String newName, int callingUid) {
         Account resultAccount = null;
         /*
          * Cancel existing notifications. Let authenticators
@@ -1038,6 +1061,8 @@
                     db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
                     db.setTransactionSuccessful();
                     isSuccessful = true;
+                    logRecord(db, DebugDbHelper.ACTION_ACCOUNT_RENAME, TABLE_ACCOUNTS, accountId,
+                            accounts);
                 }
             } finally {
                 db.endTransaction();
@@ -1131,6 +1156,8 @@
             }
         }
 
+        logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
+
         try {
             new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
         } finally {
@@ -1188,6 +1215,8 @@
             }
         }
 
+        logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
+
         try {
             new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
         } finally {
@@ -1210,6 +1239,9 @@
         if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
             return false;
         }
+
+        logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
+
         long identityToken = clearCallingIdentity();
         try {
             return removeAccountInternal(accounts, account);
@@ -1275,21 +1307,25 @@
         int deleted;
         synchronized (accounts.cacheLock) {
             final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+            final long accountId = getAccountIdLocked(db, account);
             deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
                     + "=?",
                     new String[]{account.name, account.type});
             removeAccountFromCacheLocked(accounts, account);
             sendAccountsChangedBroadcast(accounts.userId);
+
+            logRecord(db, DebugDbHelper.ACTION_ACCOUNT_REMOVE, TABLE_ACCOUNTS, accountId, accounts);
         }
         if (accounts.userId == UserHandle.USER_OWNER) {
             // Owner's account was removed, remove from any users that are sharing
             // this account.
+            int callingUid = getCallingUid();
             long id = Binder.clearCallingIdentity();
             try {
                 List<UserInfo> users = mUserManager.getUsers(true);
                 for (UserInfo user : users) {
                     if (!user.isPrimary() && user.isRestricted()) {
-                        removeSharedAccountAsUser(account, user.id);
+                        removeSharedAccountAsUser(account, user.id, callingUid);
                     }
                 }
             } finally {
@@ -1441,15 +1477,17 @@
         if (account == null) throw new IllegalArgumentException("account is null");
         checkAuthenticateAccountsPermission(account);
         UserAccounts accounts = getUserAccountsForCaller();
+        int callingUid = getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
-            setPasswordInternal(accounts, account, password);
+            setPasswordInternal(accounts, account, password, callingUid);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    private void setPasswordInternal(UserAccounts accounts, Account account, String password) {
+    private void setPasswordInternal(UserAccounts accounts, Account account, String password,
+            int callingUid) {
         if (account == null) {
             return;
         }
@@ -1473,6 +1511,11 @@
                     db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
                     accounts.authTokenCache.remove(account);
                     db.setTransactionSuccessful();
+
+                    String action = (password == null || password.length() == 0) ?
+                            DebugDbHelper.ACTION_CLEAR_PASSWORD
+                            : DebugDbHelper.ACTION_SET_PASSWORD;
+                    logRecord(db, action, TABLE_ACCOUNTS, accountId, accounts, callingUid);
                 }
             } finally {
                 db.endTransaction();
@@ -1497,9 +1540,11 @@
         if (account == null) throw new IllegalArgumentException("account is null");
         checkManageAccountsPermission();
         UserAccounts accounts = getUserAccountsForCaller();
+
+        int callingUid = getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
-            setPasswordInternal(accounts, account, null);
+            setPasswordInternal(accounts, account, null, callingUid);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -1888,6 +1933,8 @@
         options.putInt(AccountManager.KEY_CALLER_UID, uid);
         options.putInt(AccountManager.KEY_CALLER_PID, pid);
 
+        logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS);
+
         long identityToken = clearCallingIdentity();
         try {
             new Session(accounts, response, accountType, expectActivityLaunch,
@@ -1964,6 +2011,8 @@
         options.putInt(AccountManager.KEY_CALLER_UID, uid);
         options.putInt(AccountManager.KEY_CALLER_PID, pid);
 
+        logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS);
+
         long identityToken = clearCallingIdentity();
         try {
             new Session(accounts, response, accountType, expectActivityLaunch,
@@ -2320,7 +2369,8 @@
     @Override
     public boolean addSharedAccountAsUser(Account account, int userId) {
         userId = handleIncomingUser(userId);
-        SQLiteDatabase db = getUserAccounts(userId).openHelper.getWritableDatabase();
+        UserAccounts accounts = getUserAccounts(userId);
+        SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
         ContentValues values = new ContentValues();
         values.put(ACCOUNTS_NAME, account.name);
         values.put(ACCOUNTS_TYPE, account.type);
@@ -2332,6 +2382,7 @@
                     + ", skipping the DB insert failed");
             return false;
         }
+        logRecord(db, DebugDbHelper.ACTION_ACCOUNT_ADD, TABLE_SHARED_ACCOUNTS, accountId, accounts);
         return true;
     }
 
@@ -2340,6 +2391,7 @@
         userId = handleIncomingUser(userId);
         UserAccounts accounts = getUserAccounts(userId);
         SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+        long sharedTableAccountId = getAccountIdFromSharedTable(db, account);
         final ContentValues values = new ContentValues();
         values.put(ACCOUNTS_NAME, newName);
         values.put(ACCOUNTS_PREVIOUS_NAME, account.name);
@@ -2349,20 +2401,30 @@
                 ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
                 new String[] { account.name, account.type });
         if (r > 0) {
+            int callingUid = getCallingUid();
+            logRecord(db, DebugDbHelper.ACTION_ACCOUNT_RENAME, TABLE_SHARED_ACCOUNTS,
+                    sharedTableAccountId, accounts, callingUid);
             // Recursively rename the account.
-            renameAccountInternal(accounts, account, newName);
+            renameAccountInternal(accounts, account, newName, callingUid);
         }
         return r > 0;
     }
 
     @Override
     public boolean removeSharedAccountAsUser(Account account, int userId) {
+        return removeSharedAccountAsUser(account, userId, getCallingUid());
+    }
+
+    private boolean removeSharedAccountAsUser(Account account, int userId, int callingUid) {
         userId = handleIncomingUser(userId);
         UserAccounts accounts = getUserAccounts(userId);
         SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+        long sharedTableAccountId = getAccountIdFromSharedTable(db, account);
         int r = db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
                 new String[] {account.name, account.type});
         if (r > 0) {
+            logRecord(db, DebugDbHelper.ACTION_ACCOUNT_REMOVE, TABLE_SHARED_ACCOUNTS,
+                    sharedTableAccountId, accounts, callingUid);
             removeAccountInternal(accounts, account);
         }
         return r > 0;
@@ -2459,6 +2521,19 @@
         }
     }
 
+    private long getAccountIdFromSharedTable(SQLiteDatabase db, Account account) {
+        Cursor cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_ID},
+                "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
+            }
+            return -1;
+        } finally {
+            cursor.close();
+        }
+    }
+
     private long getAccountIdLocked(SQLiteDatabase db, Account account) {
         Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
                 "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
@@ -2904,6 +2979,130 @@
         return databaseFile.getPath();
     }
 
+    private static class DebugDbHelper{
+        private DebugDbHelper() {
+        }
+
+        private static String TABLE_DEBUG = "debug_table";
+
+        // Columns for the table
+        private static String ACTION_TYPE = "action_type";
+        private static String TIMESTAMP = "time";
+        private static String CALLER_UID = "caller_uid";
+        private static String TABLE_NAME = "table_name";
+        private static String KEY = "primary_key";
+
+        // These actions correspond to the occurrence of real actions. Since
+        // these are called by the authenticators, the uid associated will be
+        // of the authenticator.
+        private static String ACTION_SET_PASSWORD = "action_set_password";
+        private static String ACTION_CLEAR_PASSWORD = "action_clear_password";
+        private static String ACTION_ACCOUNT_ADD = "action_account_add";
+        private static String ACTION_ACCOUNT_REMOVE = "action_account_remove";
+        private static String ACTION_AUTHENTICATOR_REMOVE = "action_authenticator_remove";
+        private static String ACTION_ACCOUNT_RENAME = "action_account_rename";
+
+        // These actions don't necessarily correspond to any action on
+        // accountDb taking place. As an example, there might be a request for
+        // addingAccount, which might not lead to addition of account on grounds
+        // of bad authentication. We will still be logging it to keep track of
+        // who called.
+        private static String ACTION_CALLED_ACCOUNT_ADD = "action_called_account_add";
+        private static String ACTION_CALLED_ACCOUNT_REMOVE = "action_called_account_remove";
+        private static String ACTION_CALLED_ACCOUNT_RENAME = "action_called_account_rename";
+
+        private static SimpleDateFormat dateFromat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        private static String UPDATE_WHERE_CLAUSE = KEY + "=?";
+
+        private static void createDebugTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE_DEBUG + " ( "
+                    + ACCOUNTS_ID + " INTEGER,"
+                    + ACTION_TYPE + " TEXT NOT NULL, "
+                    + TIMESTAMP + " DATETIME,"
+                    + CALLER_UID + " INTEGER NOT NULL,"
+                    + TABLE_NAME + " TEXT NOT NULL,"
+                    + KEY + " INTEGER PRIMARY KEY)");
+            db.execSQL("CREATE INDEX timestamp_index ON " + TABLE_DEBUG + " (" + TIMESTAMP + ")");
+        }
+    }
+
+    private void logRecord(UserAccounts accounts, String action, String tableName) {
+        SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+        logRecord(db, action, tableName, -1, accounts);
+    }
+
+    /*
+     * This function receives an opened writable database.
+     */
+    private void logRecord(SQLiteDatabase db, String action, String tableName, long accountId,
+            UserAccounts userAccount) {
+        logRecord(db, action, tableName, accountId, userAccount, getCallingUid());
+    }
+
+    /*
+     * This function receives an opened writable database.
+     */
+    private void logRecord(SQLiteDatabase db, String action, String tableName, long accountId,
+            UserAccounts userAccount, int callingUid) {
+        SQLiteStatement logStatement = userAccount.statementForLogging;
+        logStatement.bindLong(1, accountId);
+        logStatement.bindString(2, action);
+        logStatement.bindString(3, DebugDbHelper.dateFromat.format(new Date()));
+        logStatement.bindLong(4, callingUid);
+        logStatement.bindString(5, tableName);
+        logStatement.bindLong(6, userAccount.debugDbInsertionPoint);
+        logStatement.execute();
+        logStatement.clearBindings();
+        userAccount.debugDbInsertionPoint = (userAccount.debugDbInsertionPoint + 1)
+                % MAX_DEBUG_DB_SIZE;
+    }
+
+    /*
+     * This should only be called once to compile the sql statement for logging
+     * and to find the insertion point.
+     */
+    private void initializeDebugDbSizeAndCompileSqlStatementForLogging(SQLiteDatabase db,
+            UserAccounts userAccount) {
+        // Initialize the count if not done earlier.
+        int size = (int) getDebugTableRowCount(db);
+        if (size >= MAX_DEBUG_DB_SIZE) {
+            // Table is full, and we need to find the point where to insert.
+            userAccount.debugDbInsertionPoint = (int) getDebugTableInsertionPoint(db);
+        } else {
+            userAccount.debugDbInsertionPoint = size;
+        }
+        compileSqlStatementForLogging(db, userAccount);
+    }
+
+    private void compileSqlStatementForLogging(SQLiteDatabase db, UserAccounts userAccount) {
+        String sql = "INSERT OR REPLACE INTO " + DebugDbHelper.TABLE_DEBUG
+                + " VALUES (?,?,?,?,?,?)";
+        userAccount.statementForLogging = db.compileStatement(sql);
+    }
+
+    private long getDebugTableRowCount(SQLiteDatabase db) {
+        String queryCountDebugDbRows = "SELECT COUNT(*) FROM " + DebugDbHelper.TABLE_DEBUG;
+        return DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
+    }
+
+    /*
+     * Finds the row key where the next insertion should take place. This should
+     * be invoked only if the table has reached its full capacity.
+     */
+    private long getDebugTableInsertionPoint(SQLiteDatabase db) {
+        // This query finds the smallest timestamp value (and if 2 records have
+        // same timestamp, the choose the lower id).
+        String queryCountDebugDbRows = new StringBuilder()
+                .append("SELECT ").append(DebugDbHelper.KEY)
+                .append(" FROM ").append(DebugDbHelper.TABLE_DEBUG)
+                .append(" ORDER BY ")
+                .append(DebugDbHelper.TIMESTAMP).append(",").append(DebugDbHelper.KEY)
+                .append(" LIMIT 1")
+                .toString();
+        return DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
+    }
+
     static class DatabaseHelper extends SQLiteOpenHelper {
 
         public DatabaseHelper(Context context, int userId) {
@@ -2949,6 +3148,8 @@
             createSharedAccountsTable(db);
 
             createAccountsDeletionTrigger(db);
+
+            DebugDbHelper.createDebugTable(db);
         }
 
         private void createSharedAccountsTable(SQLiteDatabase db) {
@@ -2968,6 +3169,10 @@
             db.execSQL("ALTER TABLE " + TABLE_ACCOUNTS + " ADD COLUMN " + ACCOUNTS_PREVIOUS_NAME);
         }
 
+        private void addDebugTable(SQLiteDatabase db) {
+            DebugDbHelper.createDebugTable(db);
+        }
+
         private void createAccountsDeletionTrigger(SQLiteDatabase db) {
             db.execSQL(""
                     + " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS
@@ -3028,6 +3233,11 @@
                 oldVersion++;
             }
 
+            if (oldVersion == 7) {
+                addDebugTable(db);
+                oldVersion++;
+            }
+
             if (oldVersion != newVersion) {
                 Log.e(TAG, "failed to upgrade version " + oldVersion + " to version " + newVersion);
             }
@@ -3109,6 +3319,23 @@
                     fout.println("  " + account);
                 }
 
+                // Add debug information.
+                fout.println();
+                Cursor cursor = db.query(DebugDbHelper.TABLE_DEBUG, null,
+                        null, null, null, null, DebugDbHelper.TIMESTAMP);
+                fout.println("AccountId, Action_Type, timestamp, UID, TableName, Key");
+                fout.println("Accounts History");
+                try {
+                    while (cursor.moveToNext()) {
+                        // print type,count
+                        fout.println(cursor.getString(0) + "," + cursor.getString(1) + "," +
+                                cursor.getString(2) + "," + cursor.getString(3) + ","
+                                + cursor.getString(4) + "," + cursor.getString(5));
+                    }
+                } finally {
+                    cursor.close();
+                }
+
                 fout.println();
                 synchronized (mSessions) {
                     final long now = SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4970e0f..15d7367 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -442,6 +442,12 @@
      */
     String mDeviceOwnerName;
 
+    /**
+     * Preferred activities to start on boot/user switch, as set by DevicePolicyManager. Indexed
+     * by userId.
+     */
+    SparseArray<ComponentName> mPreferredSetupActivities = new SparseArray<>();
+
     public class PendingAssistExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
         public final Bundle extras;
@@ -3334,15 +3340,22 @@
         ComponentName comp = intent.getComponent();
         try {
             if (comp != null) {
+                // Factory test.
                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
             } else {
-                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
-                        intent,
-                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            flags, userId);
+                ComponentName preferredComponent = mPreferredSetupActivities.get(userId);
+                if (preferredComponent != null) {
+                    ai = AppGlobals.getPackageManager().getActivityInfo(
+                            preferredComponent, flags, userId);
+                } else {
+                    ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
+                            intent,
+                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                                flags, userId);
 
-                if (info != null) {
-                    ai = info.activityInfo;
+                    if (info != null) {
+                        ai = info.activityInfo;
+                    }
                 }
             }
         } catch (RemoteException e) {
@@ -8574,6 +8587,22 @@
     }
 
     @Override
+    public void updatePreferredSetupActivity(ComponentName preferredActivity, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException(
+                    "updatePreferredSetupActivity called from non-system process");
+        }
+        synchronized (this) {
+            if (preferredActivity == null) {
+                mPreferredSetupActivities.delete(userId);
+            } else {
+                mPreferredSetupActivities.put(userId, preferredActivity);
+            }
+        }
+    }
+
+    @Override
     public void updateDeviceOwner(String packageName) {
         final int callingUid = Binder.getCallingUid();
         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 33f915f..62d70d2 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1331,6 +1331,9 @@
                             }
                         } catch(RemoteException e) {
                         }
+                        if (r.state == ActivityState.RESUMED) {
+                            noStackActivityResumed = false;
+                        }
                     } else {
                         // This activity is not currently visible, but is running.
                         // Tell it to become visible.
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 6b56279..eb28ed0 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1803,9 +1803,7 @@
             if (!shouldMute) {
                 // unmute
                 // ring and notifications volume should never be 0 when not silenced
-                // on voice capable devices or devices that support vibration
-                if ((isPlatformVoice() || mHasVibrator) &&
-                        mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
+                if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
                     synchronized (VolumeStreamState.class) {
                         final VolumeStreamState vss = mStreamStates[streamType];
                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
@@ -2986,10 +2984,7 @@
                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
                     }
                 } else {
-                    // (oldIndex < step) is equivalent to (old UI index == 0)
-                    if ((oldIndex < step)
-                            && mVolumePolicy.volumeDownToEnterSilent
-                            && mPrevVolDirection != AudioManager.ADJUST_LOWER) {
+                    if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
                         ringerMode = RINGER_MODE_SILENT;
                     }
                 }
@@ -3018,7 +3013,8 @@
                     if (mVolumePolicy.volumeDownToEnterSilent) {
                         final long diff = SystemClock.uptimeMillis()
                                 - mLoweredFromNormalToVibrateTime;
-                        if (diff > mVolumePolicy.vibrateToSilentDebounce) {
+                        if (diff > mVolumePolicy.vibrateToSilentDebounce
+                                && mRingerModeDelegate.canVolumeDownEnterSilent()) {
                             ringerMode = RINGER_MODE_SILENT;
                         }
                     } else {
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 93d37f1..e15bca6 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.display;
 
+import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
@@ -31,13 +32,13 @@
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
+import android.util.EventLog;
 import android.util.MathUtils;
 import android.util.Spline;
 import android.util.Slog;
 import android.util.TimeUtils;
 
 import java.io.PrintWriter;
-import java.util.Arrays;
 
 class AutomaticBrightnessController {
     private static final String TAG = "AutomaticBrightnessController";
@@ -87,7 +88,12 @@
     // well after dusk.
     private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
 
+    // Debounce for sampling user-initiated changes in display brightness to ensure
+    // the user is satisfied with the result before storing the sample.
+    private static final int BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS = 10000;
+
     private static final int MSG_UPDATE_AMBIENT_LUX = 1;
+    private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2;
 
     // Callbacks for requesting updates to the the display's power state
     private final Callbacks mCallbacks;
@@ -179,6 +185,14 @@
     // Are we going to adjust brightness while dozing.
     private boolean mDozing;
 
+    // True if we are collecting a brightness adjustment sample, along with some data
+    // for the initial state of the sample.
+    private boolean mBrightnessAdjustmentSamplePending;
+    private float mBrightnessAdjustmentSampleOldAdjustment;
+    private float mBrightnessAdjustmentSampleOldLux;
+    private int mBrightnessAdjustmentSampleOldBrightness;
+    private float mBrightnessAdjustmentSampleOldGamma;
+
     public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
             SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
             int brightnessMin, int brightnessMax, float dozeScaleFactor,
@@ -216,7 +230,8 @@
         return mScreenAutoBrightness;
     }
 
-    public void configure(boolean enable, float adjustment, boolean dozing) {
+    public void configure(boolean enable, float adjustment, boolean dozing,
+            boolean userInitiatedChange) {
         // While dozing, the application processor may be suspended which will prevent us from
         // receiving new information from the light sensor. On some devices, we may be able to
         // switch to a wake-up light sensor instead but for now we will simply disable the sensor
@@ -228,6 +243,9 @@
         if (changed) {
             updateAutoBrightness(false /*sendUpdate*/);
         }
+        if (enable && !dozing && userInitiatedChange) {
+            prepareBrightnessAdjustmentSample();
+        }
     }
 
     public void dump(PrintWriter pw) {
@@ -486,7 +504,7 @@
         }
 
         int newScreenAutoBrightness =
-            clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
+                clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
         if (mScreenAutoBrightness != newScreenAutoBrightness) {
             if (DEBUG) {
                 Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
@@ -507,6 +525,54 @@
                 mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
     }
 
+    private void prepareBrightnessAdjustmentSample() {
+        if (!mBrightnessAdjustmentSamplePending) {
+            mBrightnessAdjustmentSamplePending = true;
+            mBrightnessAdjustmentSampleOldAdjustment = mScreenAutoBrightnessAdjustment;
+            mBrightnessAdjustmentSampleOldLux = mAmbientLuxValid ? mAmbientLux : -1;
+            mBrightnessAdjustmentSampleOldBrightness = mScreenAutoBrightness;
+            mBrightnessAdjustmentSampleOldGamma = mLastScreenAutoBrightnessGamma;
+        } else {
+            mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE);
+        }
+
+        mHandler.sendEmptyMessageDelayed(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE,
+                BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS);
+    }
+
+    private void cancelBrightnessAdjustmentSample() {
+        if (mBrightnessAdjustmentSamplePending) {
+            mBrightnessAdjustmentSamplePending = false;
+            mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE);
+        }
+    }
+
+    private void collectBrightnessAdjustmentSample() {
+        if (mBrightnessAdjustmentSamplePending) {
+            mBrightnessAdjustmentSamplePending = false;
+            if (mAmbientLuxValid && mScreenAutoBrightness >= 0) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Auto-brightness adjustment changed by user: "
+                            + "adj=" + mScreenAutoBrightnessAdjustment
+                            + ", lux=" + mAmbientLux
+                            + ", brightness=" + mScreenAutoBrightness
+                            + ", gamma=" + mLastScreenAutoBrightnessGamma
+                            + ", ring=" + mAmbientLightRingBuffer);
+                }
+
+                EventLog.writeEvent(EventLogTags.AUTO_BRIGHTNESS_ADJ,
+                        mBrightnessAdjustmentSampleOldAdjustment,
+                        mBrightnessAdjustmentSampleOldLux,
+                        mBrightnessAdjustmentSampleOldBrightness,
+                        mBrightnessAdjustmentSampleOldGamma,
+                        mScreenAutoBrightnessAdjustment,
+                        mAmbientLux,
+                        mScreenAutoBrightness,
+                        mLastScreenAutoBrightnessGamma);
+            }
+        }
+    }
+
     private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
         if (lastSunset < 0 || nextSunrise < 0
                 || now < lastSunset || now > nextSunrise) {
@@ -537,6 +603,10 @@
                 case MSG_UPDATE_AMBIENT_LUX:
                     updateAmbientLux();
                     break;
+
+                case MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE:
+                    collectBrightnessAdjustmentSample();
+                    break;
             }
         }
     }
@@ -584,11 +654,7 @@
         private int mCount;
 
         public AmbientLightRingBuffer(long lightSensorRate) {
-            this((int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate));
-        }
-
-        public AmbientLightRingBuffer(int initialCapacity) {
-            mCapacity = initialCapacity;
+            mCapacity = (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate);
             mRingLux = new float[mCapacity];
             mRingTime = new long[mCapacity];
         }
@@ -664,10 +730,6 @@
             return mCount;
         }
 
-        public boolean isEmpty() {
-            return mCount == 0;
-        }
-
         public void clear() {
             mStart = 0;
             mEnd = 0;
@@ -676,27 +738,20 @@
 
         @Override
         public String toString() {
-            final int length = mCapacity - mStart;
-            float[] lux = new float[mCount];
-            long[] time = new long[mCount];
-
-            if (mCount <= length) {
-                System.arraycopy(mRingLux, mStart, lux, 0, mCount);
-                System.arraycopy(mRingTime, mStart, time, 0, mCount);
-            } else {
-                System.arraycopy(mRingLux, mStart, lux, 0, length);
-                System.arraycopy(mRingLux, 0, lux, length, mCount - length);
-
-                System.arraycopy(mRingTime, mStart, time, 0, length);
-                System.arraycopy(mRingTime, 0, time, length, mCount - length);
+            StringBuffer buf = new StringBuffer();
+            buf.append('[');
+            for (int i = 0; i < mCount; i++) {
+                final long next = i + 1 < mCount ? getTime(i + 1) : SystemClock.uptimeMillis();
+                if (i != 0) {
+                    buf.append(", ");
+                }
+                buf.append(getLux(i));
+                buf.append(" / ");
+                buf.append(next - getTime(i));
+                buf.append("ms");
             }
-            return "AmbientLightRingBuffer{mCapacity=" + mCapacity
-                + ", mStart=" + mStart
-                + ", mEnd=" + mEnd
-                + ", mCount=" + mCount
-                + ", mRingLux=" + Arrays.toString(lux)
-                + ", mRingTime=" + Arrays.toString(time)
-                + "}";
+            buf.append(']');
+            return buf.toString();
         }
 
         private int offsetOf(int index) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index f74601e..35fbef6 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -70,12 +70,11 @@
  */
 final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
     private static final String TAG = "DisplayPowerController";
+    private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
 
     private static boolean DEBUG = false;
     private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
 
-    private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
-
     // If true, uses the color fade on animation.
     // We might want to turn this off if we cannot get a guarantee that the screen
     // actually turns on and starts showing new content after the call to set the
@@ -599,8 +598,11 @@
             autoBrightnessEnabled = mPowerRequest.useAutoBrightness
                     && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                     && brightness < 0;
+            final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
+                    && mPowerRequest.brightnessSetByUser;
             mAutomaticBrightnessController.configure(autoBrightnessEnabled,
-                    mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON);
+                    mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
+                    userInitiatedChange);
         }
 
         // Apply brightness boost.
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 53ceb2e..b066d6b 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -68,7 +68,7 @@
     private static final int defaultMaxActiveJobsPerService =
             ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
     /** Amount of time a job is allowed to execute for before being considered timed-out. */
-    private static final long EXECUTING_TIMESLICE_MILLIS = 60 * 1000;
+    private static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000;
     /** Amount of time the JobScheduler will wait for a response from an app for a message. */
     private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index e106a4a..c9f5bdf 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -112,6 +112,7 @@
                 + " / " + idDebugString(baseContext, sbn.getPackageName(), notification.icon));
         pw.println(prefix + "  pri=" + notification.priority + " score=" + sbn.getScore());
         pw.println(prefix + "  key=" + sbn.getKey());
+        pw.println(prefix + "  seen=" + mIsSeen);
         pw.println(prefix + "  groupKey=" + getGroupKey());
         pw.println(prefix + "  contentIntent=" + notification.contentIntent);
         pw.println(prefix + "  deleteIntent=" + notification.deleteIntent);
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index 1e318ef..44fbd2d 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -115,8 +115,8 @@
         append(TYPE_UNSUBSCRIBE, uri + "," + subscribeResult(provider, e));
     }
 
-    public static void traceConfig(ZenModeConfig oldConfig, ZenModeConfig newConfig) {
-        append(TYPE_CONFIG, newConfig != null ? newConfig.toString() : null);
+    public static void traceConfig(String reason, ZenModeConfig newConfig) {
+        append(TYPE_CONFIG, reason + "," + (newConfig != null ? newConfig.toString() : null));
     }
 
     public static void traceDisableEffects(NotificationRecord record, String reason) {
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 9cb8af5..83f0bcfc 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -17,6 +17,7 @@
 package com.android.server.notification;
 
 import static android.media.AudioAttributes.USAGE_ALARM;
+import static android.media.AudioAttributes.USAGE_MEDIA;
 import static android.media.AudioAttributes.USAGE_NOTIFICATION;
 import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
 
@@ -262,8 +263,8 @@
         }
         mConditions.evaluateConfig(config);  // may modify config
         if (config.equals(mConfig)) return true;
-        if (DEBUG) Log.d(TAG, "setConfig reason=" + reason);
-        ZenLog.traceConfig(mConfig, config);
+        if (DEBUG) Log.d(TAG, "setConfig reason=" + reason, new Throwable());
+        ZenLog.traceConfig(reason, config);
         final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
                 getNotificationPolicy(config));
         mConfig = config;
@@ -329,9 +330,10 @@
                 || mEffectsSuppressed;
         applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE);
 
-        // alarm restrictions
-        final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
-        applyRestrictions(muteAlarms, USAGE_ALARM);
+        // alarm/media restrictions
+        final boolean zenNone = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
+        applyRestrictions(zenNone, USAGE_ALARM);
+        applyRestrictions(zenNone, USAGE_MEDIA);
     }
 
     private void applyRestrictions(boolean mute, int usage) {
@@ -590,6 +592,11 @@
                     ringerModeInternal, ringerModeInternalOut);
             return ringerModeInternalOut;
         }
+
+        @Override
+        public boolean canVolumeDownEnterSilent() {
+            return mZenMode == Global.ZEN_MODE_OFF;
+        }
     }
 
     private final class SettingsObserver extends ContentObserver {
diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java
index c8e5c3a..7531403 100644
--- a/services/core/java/com/android/server/pm/KeySetManagerService.java
+++ b/services/core/java/com/android/server/pm/KeySetManagerService.java
@@ -58,9 +58,9 @@
 
     private final ArrayMap<String, PackageSetting> mPackages;
 
-    private static long lastIssuedKeySetId = 0;
+    private long lastIssuedKeySetId = 0;
 
-    private static long lastIssuedKeyId = 0;
+    private long lastIssuedKeyId = 0;
 
     class PublicKeyHandle {
         private final PublicKey mKey;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f087c33..8a19056 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -49,6 +49,7 @@
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+import static android.content.pm.PackageManager.MATCH_ALL;
 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
@@ -2274,6 +2275,13 @@
                 }
                 continue;
             }
+            if (!pkg.isSystemApp()) {
+                if (logging) {
+                    Slog.d(TAG, "No priming domain verifications for a non system package : " +
+                            packageName);
+                }
+                continue;
+            }
             for (PackageParser.Activity a : pkg.activities) {
                 for (ActivityIntentInfo filter : a.intents) {
                     if (hasValidDomains(filter, false)) {
@@ -2281,7 +2289,7 @@
                     }
                 }
             }
-            if (allHosts.size() > 0) {
+            if (allHosts.size() == 0) {
                 allHosts.add("*");
             }
             IntentFilterVerificationInfo ivi =
@@ -3921,25 +3929,26 @@
                 // Check for results that need to skip the current profile.
                 ResolveInfo resolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
                         resolvedType, flags, userId);
-                if (resolveInfo != null) {
+                if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) {
                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
                     result.add(resolveInfo);
                     return filterIfNotPrimaryUser(result, userId);
                 }
-                // Check for cross profile results.
-                resolveInfo = queryCrossProfileIntents(
-                        matchingFilters, intent, resolvedType, flags, userId);
 
                 // Check for results in the current profile.
                 List<ResolveInfo> result = mActivities.queryIntent(
                         intent, resolvedType, flags, userId);
-                if (resolveInfo != null) {
+
+                // Check for cross profile results.
+                resolveInfo = queryCrossProfileIntents(
+                        matchingFilters, intent, resolvedType, flags, userId);
+                if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) {
                     result.add(resolveInfo);
                     Collections.sort(result, mResolvePrioritySorter);
                 }
                 result = filterIfNotPrimaryUser(result, userId);
                 if (result.size() > 1 && hasWebURI(intent)) {
-                    return filterCandidatesWithDomainPreferedActivitiesLPr(result);
+                    return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result);
                 }
                 return result;
             }
@@ -3954,6 +3963,16 @@
         }
     }
 
+    private boolean isUserEnabled(int userId) {
+        long callingId = Binder.clearCallingIdentity();
+        try {
+            UserInfo userInfo = sUserManager.getUserInfo(userId);
+            return userInfo != null && userInfo.isEnabled();
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
     /**
      * Filter out activities with primaryUserOnly flag set, when current user is not the owner.
      *
@@ -3984,7 +4003,7 @@
     }
 
     private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr(
-            List<ResolveInfo> candidates) {
+            int flags, List<ResolveInfo> candidates) {
         if (DEBUG_PREFERRED) {
             Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " +
                     candidates.size());
@@ -4004,6 +4023,11 @@
                 String packageName = info.activityInfo.packageName;
                 PackageSetting ps = mSettings.mPackages.get(packageName);
                 if (ps != null) {
+                    // Add to the special match all list (Browser use case)
+                    if (info.handleAllWebDataURI) {
+                        matchAllList.add(info);
+                        continue;
+                    }
                     // Try to get the status from User settings first
                     int status = getDomainVerificationStatusLPr(ps, userId);
                     if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
@@ -4013,10 +4037,6 @@
                     } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
                         undefinedList.add(info);
                     }
-                    // Add to the special match all list (Browser use case)
-                    if (info.handleAllWebDataURI) {
-                        matchAllList.add(info);
-                    }
                 }
             }
             // If there is nothing selected, add all candidates and remove the ones that the User
@@ -4031,7 +4051,30 @@
             result.removeAll(matchAllList);
             if (result.size() == 0) {
                 result.addAll(undefinedList);
-                result.addAll(matchAllList);
+                if ((flags & MATCH_ALL) != 0) {
+                    result.addAll(matchAllList);
+                } else {
+                    // Try to add the Default Browser if we can
+                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(
+                            UserHandle.myUserId());
+                    if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
+                        boolean defaultBrowserFound = false;
+                        final int browserCount = matchAllList.size();
+                        for (int n=0; n<browserCount; n++) {
+                            ResolveInfo browser = matchAllList.get(n);
+                            if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) {
+                                result.add(browser);
+                                defaultBrowserFound = true;
+                                break;
+                            }
+                        }
+                        if (!defaultBrowserFound) {
+                            result.addAll(matchAllList);
+                        }
+                    } else {
+                        result.addAll(matchAllList);
+                    }
+                }
             }
         }
         if (DEBUG_PREFERRED) {
@@ -11331,10 +11374,16 @@
                                 verifierUid, userId, verificationId, filter, packageName);
                         count++;
                     } else if (!needsFilterVerification) {
-                        Slog.d(TAG, "No verification needed for IntentFilter:"
-                                + filter.toString());
+                        Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString());
                         if (hasValidDomains(filter)) {
-                            allHosts.addAll(filter.getHostsList());
+                            ArrayList<String> hosts = filter.getHostsList();
+                            if (hosts.size() > 0) {
+                                allHosts.addAll(hosts);
+                            } else {
+                                if (allHosts.isEmpty()) {
+                                    allHosts.add("*");
+                                }
+                            }
                         }
                     } else {
                         Slog.d(TAG, "Verification already done for IntentFilter:"
@@ -14154,7 +14203,8 @@
             movePackageInternal(packageName, volumeUuid, moveId);
         } catch (PackageManagerException e) {
             Slog.d(TAG, "Failed to move " + packageName, e);
-            mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
+            mMoveCallbacks.notifyStatusChanged(moveId, null,
+                    PackageManager.MOVE_FAILED_INTERNAL_ERROR);
         }
         return moveId;
     }
@@ -14171,6 +14221,7 @@
         final String packageAbiOverride;
         final int appId;
         final String seinfo;
+        final String moveTitle;
 
         // reader
         synchronized (mPackages) {
@@ -14190,9 +14241,6 @@
 
             // TODO: yell if already in desired location
 
-            mMoveCallbacks.notifyStarted(moveId,
-                    String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)));
-
             pkg.mOperationPending = true;
 
             currentAsec = pkg.applicationInfo.isForwardLocked()
@@ -14203,6 +14251,7 @@
             packageAbiOverride = ps.cpuAbiOverrideString;
             appId = UserHandle.getAppId(pkg.applicationInfo.uid);
             seinfo = pkg.applicationInfo.seinfo;
+            moveTitle = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
         }
 
         int installFlags;
@@ -14230,7 +14279,7 @@
         }
 
         Slog.d(TAG, "Moving " + packageName + " from " + currentVolumeUuid + " to " + volumeUuid);
-        mMoveCallbacks.notifyStatusChanged(moveId, 10, -1);
+        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle, 10);
 
         if (moveData) {
             synchronized (mInstallLock) {
@@ -14250,7 +14299,7 @@
             }
         }
 
-        mMoveCallbacks.notifyStatusChanged(moveId, 50);
+        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle, 50);
 
         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
             @Override
@@ -14277,15 +14326,15 @@
                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
                 switch (status) {
                     case PackageInstaller.STATUS_SUCCESS:
-                        mMoveCallbacks.notifyStatusChanged(moveId,
+                        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
                                 PackageManager.MOVE_SUCCEEDED);
                         break;
                     case PackageInstaller.STATUS_FAILURE_STORAGE:
-                        mMoveCallbacks.notifyStatusChanged(moveId,
+                        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
                                 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
                         break;
                     default:
-                        mMoveCallbacks.notifyStatusChanged(moveId,
+                        mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
                                 PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                         break;
                 }
@@ -14308,15 +14357,12 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
 
         final int realMoveId = mNextMoveId.getAndIncrement();
+        final String realTitle = null;
+
         final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
             @Override
-            public void onStarted(int moveId, String title) {
-                // Ignored
-            }
-
-            @Override
-            public void onStatusChanged(int moveId, int status, long estMillis) {
-                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
+            public void onStatusChanged(int moveId, String title, int status, long estMillis) {
+                mMoveCallbacks.notifyStatusChanged(realMoveId, realTitle, status, estMillis);
             }
         };
 
@@ -14671,7 +14717,6 @@
     }
 
     private static class MoveCallbacks extends Handler {
-        private static final int MSG_STARTED = 1;
         private static final int MSG_STATUS_CHANGED = 2;
 
         private final RemoteCallbackList<IPackageMoveObserver>
@@ -14709,37 +14754,26 @@
         private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
                 throws RemoteException {
             switch (what) {
-                case MSG_STARTED: {
-                    callback.onStarted(args.argi1, (String) args.arg2);
-                    break;
-                }
                 case MSG_STATUS_CHANGED: {
-                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
+                    callback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
+                            (long) args.arg4);
                     break;
                 }
             }
         }
 
-        private void notifyStarted(int moveId, String title) {
-            Slog.v(TAG, "Move " + moveId + " started with title " + title);
-
-            final SomeArgs args = SomeArgs.obtain();
-            args.argi1 = moveId;
-            args.arg2 = title;
-            obtainMessage(MSG_STARTED, args).sendToTarget();
+        private void notifyStatusChanged(int moveId, String moveTitle, int status) {
+            notifyStatusChanged(moveId, moveTitle, status, -1);
         }
 
-        private void notifyStatusChanged(int moveId, int status) {
-            notifyStatusChanged(moveId, status, -1);
-        }
-
-        private void notifyStatusChanged(int moveId, int status, long estMillis) {
+        private void notifyStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
             Slog.v(TAG, "Move " + moveId + " status " + status);
 
             final SomeArgs args = SomeArgs.obtain();
             args.argi1 = moveId;
-            args.argi2 = status;
-            args.arg3 = estMillis;
+            args.arg2 = moveTitle;
+            args.argi3 = status;
+            args.arg4 = estMillis;
             obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
 
             synchronized (mLastStatus) {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 926090e..01c110f 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -41,11 +41,13 @@
     private volatile boolean mSimSecure;
     private volatile boolean mInputRestricted;
 
+    private int mCurrentUserId;
+
     private final LockPatternUtils mLockPatternUtils;
 
     public KeyguardStateMonitor(Context context, IKeyguardService service) {
         mLockPatternUtils = new LockPatternUtils(context);
-        mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
+        mCurrentUserId = ActivityManager.getCurrentUser();
         try {
             service.addStateMonitorCallback(this);
         } catch (RemoteException e) {
@@ -58,7 +60,7 @@
     }
 
     public boolean isSecure() {
-        return mLockPatternUtils.isSecure() || mSimSecure;
+        return mLockPatternUtils.isSecure(getCurrentUser()) || mSimSecure;
     }
 
     public boolean isInputRestricted() {
@@ -75,8 +77,12 @@
         mSimSecure = simSecure;
     }
 
-    public void setCurrentUser(int userId) {
-        mLockPatternUtils.setCurrentUser(userId);
+    public synchronized void setCurrentUser(int userId) {
+        mCurrentUserId = userId;
+    }
+
+    private synchronized int getCurrentUser() {
+        return mCurrentUserId;
     }
 
     @Override // Binder interface
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 6c8959c..f790f75 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1819,6 +1819,7 @@
             mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
 
             // Determine appropriate screen brightness and auto-brightness adjustments.
+            boolean brightnessSetByUser = true;
             int screenBrightness = mScreenBrightnessSettingDefault;
             float screenAutoBrightnessAdjustment = 0.0f;
             boolean autoBrightness = (mScreenBrightnessModeSetting ==
@@ -1826,6 +1827,7 @@
             if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
                 screenBrightness = mScreenBrightnessOverrideFromWindowManager;
                 autoBrightness = false;
+                brightnessSetByUser = false;
             } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
                 screenBrightness = mTemporaryScreenBrightnessSettingOverride;
             } else if (isValidBrightness(mScreenBrightnessSetting)) {
@@ -1851,6 +1853,7 @@
             mDisplayPowerRequest.screenBrightness = screenBrightness;
             mDisplayPowerRequest.screenAutoBrightnessAdjustment =
                     screenAutoBrightnessAdjustment;
+            mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
             mDisplayPowerRequest.useAutoBrightness = autoBrightness;
             mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
             mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 184224b..5669f30 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -59,7 +59,8 @@
     // for disabling the status bar
     private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
     private IBinder mSysUiVisToken = new Binder();
-    private int mDisabled = 0;
+    private int mDisabled1 = 0;
+    private int mDisabled2 = 0;
 
     private Object mLock = new Object();
     // encompasses lights-out mode and other flags defined on View
@@ -74,12 +75,14 @@
     private class DisableRecord implements IBinder.DeathRecipient {
         int userId;
         String pkg;
-        int what;
+        int what1;
+        int what2;
         IBinder token;
 
         public void binderDied() {
             Slog.i(TAG, "binder died for pkg=" + pkg);
             disableForUser(0, token, pkg, userId);
+            disable2ForUser(0, token, pkg, userId);
             token.unlinkToDeath(this, 0);
         }
     }
@@ -202,29 +205,57 @@
         enforceStatusBar();
 
         synchronized (mLock) {
-            disableLocked(userId, what, token, pkg);
+            disableLocked(userId, what, token, pkg, 1);
         }
     }
 
-    private void disableLocked(int userId, int what, IBinder token, String pkg) {
+    /**
+     * Disable additional status bar features. Pass the bitwise-or of the DISABLE2_* flags.
+     * To re-enable everything, pass {@link #DISABLE_NONE}.
+     *
+     * Warning: Only pass DISABLE2_* flags into this function, do not use DISABLE_* flags.
+     */
+    @Override
+    public void disable2(int what, IBinder token, String pkg) {
+        disableForUser(what, token, pkg, mCurrentUserId);
+    }
+
+    /**
+     * Disable additional status bar features for a given user. Pass the bitwise-or of the
+     * DISABLE2_* flags. To re-enable everything, pass {@link #DISABLE_NONE}.
+     *
+     * Warning: Only pass DISABLE2_* flags into this function, do not use DISABLE_* flags.
+     */
+    @Override
+    public void disable2ForUser(int what, IBinder token, String pkg, int userId) {
+        enforceStatusBar();
+
+        synchronized (mLock) {
+            disableLocked(userId, what, token, pkg, 2);
+        }
+    }
+
+    private void disableLocked(int userId, int what, IBinder token, String pkg, int whichFlag) {
         // It's important that the the callback and the call to mBar get done
         // in the same order when multiple threads are calling this function
         // so they are paired correctly.  The messages on the handler will be
         // handled in the order they were enqueued, but will be outside the lock.
-        manageDisableListLocked(userId, what, token, pkg);
+        manageDisableListLocked(userId, what, token, pkg, whichFlag);
 
         // Ensure state for the current user is applied, even if passed a non-current user.
-        final int net = gatherDisableActionsLocked(mCurrentUserId);
-        if (net != mDisabled) {
-            mDisabled = net;
+        final int net1 = gatherDisableActionsLocked(mCurrentUserId, 1);
+        final int net2 = gatherDisableActionsLocked(mCurrentUserId, 2);
+        if (net1 != mDisabled1 || net2 != mDisabled2) {
+            mDisabled1 = net1;
+            mDisabled2 = net2;
             mHandler.post(new Runnable() {
                     public void run() {
-                        mNotificationDelegate.onSetDisabled(net);
+                        mNotificationDelegate.onSetDisabled(net1);
                     }
                 });
             if (mBar != null) {
                 try {
-                    mBar.disable(net);
+                    mBar.disable(net1, net2);
                 } catch (RemoteException ex) {
                 }
             }
@@ -375,7 +406,7 @@
                     mCurrentUserId,
                     vis & StatusBarManager.DISABLE_MASK,
                     mSysUiVisToken,
-                    cause);
+                    cause, 1);
         }
     }
 
@@ -513,12 +544,13 @@
             iconList.copyFrom(mIcons);
         }
         synchronized (mLock) {
-            switches[0] = gatherDisableActionsLocked(mCurrentUserId);
+            switches[0] = gatherDisableActionsLocked(mCurrentUserId, 1);
             switches[1] = mSystemUiVisibility;
             switches[2] = mMenuVisible ? 1 : 0;
             switches[3] = mImeWindowVis;
             switches[4] = mImeBackDisposition;
             switches[5] = mShowImeSwitcher ? 1 : 0;
+            switches[6] = gatherDisableActionsLocked(mCurrentUserId, 2);
             binders.add(mImeToken);
         }
     }
@@ -660,7 +692,7 @@
     // ================================================================================
 
     // lock on mDisableRecords
-    void manageDisableListLocked(int userId, int what, IBinder token, String pkg) {
+    void manageDisableListLocked(int userId, int what, IBinder token, String pkg, int which) {
         if (SPEW) {
             Slog.d(TAG, "manageDisableList userId=" + userId
                     + " what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
@@ -693,21 +725,25 @@
                 }
                 mDisableRecords.add(tok);
             }
-            tok.what = what;
+            if (which == 1) {
+                tok.what1 = what;
+            } else {
+                tok.what2 = what;
+            }
             tok.token = token;
             tok.pkg = pkg;
         }
     }
 
     // lock on mDisableRecords
-    int gatherDisableActionsLocked(int userId) {
+    int gatherDisableActionsLocked(int userId, int which) {
         final int N = mDisableRecords.size();
         // gather the new net flags
         int net = 0;
         for (int i=0; i<N; i++) {
             final DisableRecord rec = mDisableRecords.get(i);
             if (rec.userId == userId) {
-                net |= rec.what;
+                net |= (which == 1) ? rec.what1 : rec.what2;
             }
         }
         return net;
@@ -731,13 +767,15 @@
         }
 
         synchronized (mLock) {
-            pw.println("  mDisabled=0x" + Integer.toHexString(mDisabled));
+            pw.println("  mDisabled1=0x" + Integer.toHexString(mDisabled1));
+            pw.println("  mDisabled2=0x" + Integer.toHexString(mDisabled2));
             final int N = mDisableRecords.size();
             pw.println("  mDisableRecords.size=" + N);
             for (int i=0; i<N; i++) {
                 DisableRecord tok = mDisableRecords.get(i);
                 pw.println("    [" + i + "] userId=" + tok.userId
-                                + " what=0x" + Integer.toHexString(tok.what)
+                                + " what1=0x" + Integer.toHexString(tok.what1)
+                                + " what2=0x" + Integer.toHexString(tok.what2)
                                 + " pkg=" + tok.pkg
                                 + " token=" + tok.token);
             }
diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java
index e226e3d..ba3ce36 100644
--- a/services/core/java/com/android/server/wm/Watermark.java
+++ b/services/core/java/com/android/server/wm/Watermark.java
@@ -84,7 +84,7 @@
         int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
                 TypedValue.COMPLEX_UNIT_DIP, 20, dm);
 
-        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mTextPaint = new Paint();
         mTextPaint.setTextSize(fontSize);
         mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c5bdbb0..d4b3dab 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2345,7 +2345,6 @@
 
         boolean reportNewConfig = false;
         WindowState attachedWindow = null;
-        WindowState win = null;
         long origId;
         final int type = attrs.type;
 
@@ -2482,7 +2481,7 @@
                 addToken = true;
             }
 
-            win = new WindowState(this, session, client, token,
+            WindowState win = new WindowState(this, session, client, token,
                     attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
             if (win.mDeathRecipient == null) {
                 // Client has apparently died, so there is no reason to
@@ -9941,18 +9940,20 @@
 
                     final WindowStateAnimator winAnimator = w.mWinAnimator;
 
-                    // If the window has moved due to its containing
-                    // content frame changing, then we'd like to animate
-                    // it.
-                    if (w.mHasSurface && w.shouldAnimateMove()) {
-                        // Frame has moved, containing content frame
-                        // has also moved, and we're not currently animating...
-                        // let's do something.
-                        Animation a = AnimationUtils.loadAnimation(mContext,
-                                com.android.internal.R.anim.window_move_from_decor);
-                        winAnimator.setAnimation(a);
-                        winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
-                        winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+                    // If the window has moved due to its containing content frame changing, then
+                    // notify the listeners and optionally animate it.
+                    if (w.hasMoved()) {
+                        // Frame has moved, containing content frame has also moved, and we're not
+                        // currently animating... let's do something.
+                        final int left = w.mFrame.left;
+                        final int top = w.mFrame.top;
+                        if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
+                            Animation a = AnimationUtils.loadAnimation(mContext,
+                                    com.android.internal.R.anim.window_move_from_decor);
+                            winAnimator.setAnimation(a);
+                            winAnimator.mAnimDw = w.mLastFrame.left - left;
+                            winAnimator.mAnimDh = w.mLastFrame.top - top;
+                        }
 
                         //TODO (multidisplay): Accessibility supported only for the default display.
                         if (mAccessibilityController != null
@@ -9961,7 +9962,7 @@
                         }
 
                         try {
-                            w.mClient.moved(w.mFrame.left, w.mFrame.top);
+                            w.mClient.moved(left, top);
                         } catch (RemoteException e) {
                         }
                     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ec70879..ad25462 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -20,7 +20,6 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -1081,16 +1080,14 @@
     }
 
     /**
-     * Return whether this window is wanting to have a translation
-     * animation applied to it for an in-progress move.  (Only makes
+     * Return whether this window has moved. (Only makes
      * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
      */
-    boolean shouldAnimateMove() {
-        return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay()
-                && (mFrame.top != mLastFrame.top
+    boolean hasMoved() {
+        return mHasSurface && mContentChanged && !mExiting && !mWinAnimator.mLastHidden
+                && mService.okToDisplay() && (mFrame.top != mLastFrame.top
                         || mFrame.left != mLastFrame.left)
-                && (mAttrs.privateFlags&PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
-                && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove());
+                && (mAttachedWindow == null || !mAttachedWindow.hasMoved());
     }
 
     boolean isFullscreen(int screenWidth, int screenHeight) {
@@ -1709,7 +1706,7 @@
                     pw.println(mWallpaperDisplayOffsetY);
         }
         if (mDrawLock != null) {
-            pw.println("mDrawLock=" + mDrawLock);
+            pw.print(prefix); pw.println("mDrawLock=" + mDrawLock);
         }
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2b88158..f801d2d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -181,6 +181,8 @@
 
     private static final String ATTR_PERMISSION_PROVIDER = "permission-provider";
     private static final String ATTR_SETUP_COMPLETE = "setup-complete";
+    private static final String ATTR_PREFERRED_SETUP_ACTIVITY = "setup-activity";
+    private static final String ATTR_PERMISSION_POLICY = "permission-policy";
 
     private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer";
 
@@ -190,6 +192,9 @@
             StatusBarManager.DISABLE_NOTIFICATION_ALERTS |
             StatusBarManager.DISABLE_SEARCH;
 
+    private static final int STATUS_BAR_DISABLE2_MASK =
+            StatusBarManager.DISABLE2_QUICK_SETTINGS;
+
     private static final Set<String> DEVICE_OWNER_USER_RESTRICTIONS;
     static {
         DEVICE_OWNER_USER_RESTRICTIONS = new HashSet();
@@ -299,6 +304,7 @@
         int mPasswordOwner = -1;
         long mLastMaximumTimeToLock = -1;
         boolean mUserSetupComplete = false;
+        int mPermissionPolicy;
 
         final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<>();
         final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>();
@@ -315,6 +321,8 @@
 
         boolean doNotAskCredentialsOnBoot = false;
 
+        ComponentName mPreferredSetupActivity;
+
         public DevicePolicyData(int userHandle) {
             mUserHandle = userHandle;
         }
@@ -1406,11 +1414,20 @@
                 out.attribute(null, ATTR_SETUP_COMPLETE,
                         Boolean.toString(true));
             }
+            if (policy.mPermissionPolicy != DevicePolicyManager.PERMISSION_POLICY_PROMPT) {
+                out.attribute(null, ATTR_PERMISSION_POLICY,
+                        Integer.toString(policy.mPermissionPolicy));
+            }
             if (policy.mDelegatedCertInstallerPackage != null) {
                 out.attribute(null, ATTR_DELEGATED_CERT_INSTALLER,
                         policy.mDelegatedCertInstallerPackage);
             }
-
+            if (policy.mPreferredSetupActivity != null) {
+                out.attribute(null, ATTR_PREFERRED_SETUP_ACTIVITY,
+                        policy.mPreferredSetupActivity.flattenToString());
+            } else {
+                out.attribute(null, ATTR_PREFERRED_SETUP_ACTIVITY, "");
+            }
 
             final int N = policy.mAdminList.size();
             for (int i=0; i<N; i++) {
@@ -1529,8 +1546,18 @@
             if (userSetupComplete != null && Boolean.toString(true).equals(userSetupComplete)) {
                 policy.mUserSetupComplete = true;
             }
+            String permissionPolicy = parser.getAttributeValue(null, ATTR_PERMISSION_POLICY);
+            if (!TextUtils.isEmpty(permissionPolicy)) {
+                policy.mPermissionPolicy = Integer.parseInt(permissionPolicy);
+            }
             policy.mDelegatedCertInstallerPackage = parser.getAttributeValue(null,
                     ATTR_DELEGATED_CERT_INSTALLER);
+            String preferredSetupActivity =
+                    parser.getAttributeValue(null, ATTR_PREFERRED_SETUP_ACTIVITY);
+            if (preferredSetupActivity != null) {
+                policy.mPreferredSetupActivity =
+                        ComponentName.unflattenFromString(preferredSetupActivity);
+            }
 
             type = parser.next();
             int outerDepth = parser.getDepth();
@@ -1654,6 +1681,7 @@
         if (!policy.mStatusBarEnabledState) {
             setStatusBarEnabledStateInternal(policy.mStatusBarEnabledState, userHandle);
         }
+        updatePreferredSetupActivityLocked(userHandle);
     }
 
     private void updateLockTaskPackagesLocked(List<String> packages, int userId) {
@@ -4238,14 +4266,22 @@
             return;
         }
         UserHandle callingUser = Binder.getCallingUserHandle();
+        int userId = callingUser.getIdentifier();
         // Check if this is the profile owner who is calling
         getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
         synchronized (this) {
+            // Reset some of the profile-owner policies
+            DevicePolicyData policy = getUserData(userId);
+            policy.mPermissionPolicy = DevicePolicyManager.PERMISSION_POLICY_PROMPT;
+            policy.mDelegatedCertInstallerPackage = null;
+            policy.mStatusBarEnabledState = true;
+            saveSettingsLocked(userId);
+
             long ident = Binder.clearCallingIdentity();
             try {
                 clearUserRestrictions(callingUser);
                 if (mDeviceOwner != null) {
-                    mDeviceOwner.removeProfileOwner(callingUser.getIdentifier());
+                    mDeviceOwner.removeProfileOwner(userId);
                     mDeviceOwner.writeOwnerFile();
                 }
             } finally {
@@ -4632,6 +4668,43 @@
     }
 
     @Override
+    public void setPreferredSetupActivity(ComponentName who, ComponentName activity) {
+        if (!mHasFeature) {
+            return;
+        }
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        synchronized (this) {
+            ActiveAdmin activeAdmin =
+                    getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            if (!isDeviceInitializer(activeAdmin.info.getPackageName())) {
+                throw new SecurityException(
+                        "This method can only be called by device initializers");
+            }
+            int userHandle = UserHandle.getCallingUserId();
+            DevicePolicyData userData = getUserData(userHandle);
+            userData.mPreferredSetupActivity = activity;
+            saveSettingsLocked(userHandle);
+            updatePreferredSetupActivityLocked(userHandle);
+        }
+    }
+
+    private void updatePreferredSetupActivityLocked(int userHandle) {
+        if (!mHasFeature) {
+            return;
+        }
+        IActivityManager am = ActivityManagerNative.getDefault();
+        long ident = Binder.clearCallingIdentity();
+        try {
+            am.updatePreferredSetupActivity(
+                    getUserData(userHandle).mPreferredSetupActivity, userHandle);
+        } catch (RemoteException e) {
+            // Not gonna happen.
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
     public void setApplicationRestrictions(ComponentName who, String packageName, Bundle settings) {
         Preconditions.checkNotNull(who, "ComponentName is null");
         final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
@@ -5970,8 +6043,10 @@
             IStatusBarService statusBarService = IStatusBarService.Stub.asInterface(
                     ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
             if (statusBarService != null) {
-                int flags = enabled ? StatusBarManager.DISABLE_NONE : STATUS_BAR_DISABLE_MASK;
-                statusBarService.disableForUser(flags, mToken, mContext.getPackageName(), userId);
+                int flags1 = enabled ? StatusBarManager.DISABLE_NONE : STATUS_BAR_DISABLE_MASK;
+                int flags2 = enabled ? StatusBarManager.DISABLE2_NONE : STATUS_BAR_DISABLE2_MASK;
+                statusBarService.disableForUser(flags1, mToken, mContext.getPackageName(), userId);
+                statusBarService.disable2ForUser(flags2, mToken, mContext.getPackageName(), userId);
             }
         } catch (RemoteException e) {
             Slog.e(LOG_TAG, "Failed to disable the status bar", e);
@@ -6000,6 +6075,9 @@
                 if (!policy.mUserSetupComplete) {
                     policy.mUserSetupComplete = true;
                     synchronized (this) {
+                        // Clear the preferred setup activity.
+                        policy.mPreferredSetupActivity = null;
+                        updatePreferredSetupActivityLocked(userHandle);
                         // The DeviceInitializer was whitelisted but now should be removed.
                         removeDeviceInitializerFromLockTaskPackages(userHandle);
                         saveSettingsLocked(userHandle);
@@ -6206,4 +6284,48 @@
             }
         }
     }
+
+    @Override
+    public void setPermissionPolicy(ComponentName admin, int policy) throws RemoteException {
+        int userId = UserHandle.getCallingUserId();
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            DevicePolicyData userPolicy = getUserData(userId);
+            if (userPolicy.mPermissionPolicy != policy) {
+                userPolicy.mPermissionPolicy = policy;
+                saveSettingsLocked(userId);
+            }
+        }
+    }
+
+    @Override
+    public int getPermissionPolicy(ComponentName admin) throws RemoteException {
+        int userId = UserHandle.getCallingUserId();
+        synchronized (this) {
+            DevicePolicyData userPolicy = getUserData(userId);
+            return userPolicy.mPermissionPolicy;
+        }
+    }
+
+    @Override
+    public boolean setPermissionGranted(ComponentName admin, String packageName,
+            String permission, boolean granted) throws RemoteException {
+        UserHandle user = Binder.getCallingUserHandle();
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            long ident = Binder.clearCallingIdentity();
+            try {
+                if (granted) {
+                    mContext.getPackageManager().grantPermission(packageName, permission, user);
+                } else {
+                    mContext.getPackageManager().revokePermission(packageName, permission, user);
+                }
+                return true;
+            } catch (SecurityException se) {
+                return false;
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
new file mode 100644
index 0000000..2557974
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
@@ -0,0 +1,804 @@
+/*
+ * 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.server.pm;
+
+
+import android.content.pm.PackageParser;
+import android.content.pm.Signature;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.LongSparseArray;
+import com.android.internal.util.ArrayUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.PublicKey;
+
+import android.test.AndroidTestCase;
+
+public class KeySetManagerServiceTest extends AndroidTestCase {
+
+    private ArrayMap<String, PackageSetting> mPackagesMap;
+    private KeySetManagerService mKsms;
+
+    public PackageSetting generateFakePackageSetting(String name) {
+        return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"),
+                new File(mContext.getCacheDir(), "fakeResPath"), "", "", "",
+                "", 1, 0, 0);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mPackagesMap = new ArrayMap<String, PackageSetting>();
+        mKsms = new KeySetManagerService(mPackagesMap);
+    }
+
+    public void testPackageKeySetDataConstructorUnassignend() {
+        PackageKeySetData pksd = new PackageKeySetData();
+        assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, pksd.getProperSigningKeySet());
+        assertNull(pksd.getUpgradeKeySets());
+        ArrayMap<String, Long> aliases = pksd.getAliases();
+        assertNotNull(aliases);
+        assertEquals(0, aliases.size());
+    }
+
+    /* test equivalence of PackageManager cert encoding and PackageParser manifest keys */
+    public void testPublicKeyCertReprEquiv() throws CertificateException {
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+
+        Signature sigA = new Signature(KeySetStrings.ctsKeySetCertA);
+        Signature sigB = new Signature(KeySetStrings.ctsKeySetCertB);
+        Signature sigC = new Signature(KeySetStrings.ctsKeySetCertC);
+
+        assertNotNull(keyA);
+        assertNotNull(keyB);
+        assertNotNull(keyC);
+
+        assertEquals(keyA, sigA.getPublicKey());
+        assertEquals(keyB, sigB.getPublicKey());
+        assertEquals(keyC, sigC.getPublicKey());
+
+        byte[] bArrayPk = keyA.getEncoded();
+        byte[] bArrayCert = sigA.getPublicKey().getEncoded();
+        assertEquals(bArrayPk.length, bArrayCert.length);
+        assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length));
+
+        bArrayPk = keyB.getEncoded();
+        bArrayCert = sigB.getPublicKey().getEncoded();
+        assertEquals(bArrayPk.length, bArrayCert.length);
+        assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length));
+
+        bArrayPk = keyC.getEncoded();
+        bArrayCert = sigC.getPublicKey().getEncoded();
+        assertEquals(bArrayPk.length, bArrayCert.length);
+        assertEquals(true, ArrayUtils.equals(bArrayPk, bArrayCert, bArrayPk.length));
+    }
+
+    public void testEncodePublicKey() throws IOException {
+        ArrayMap<String, PackageSetting> packagesMap = new ArrayMap<String, PackageSetting>();
+        KeySetManagerService ksms = new KeySetManagerService(packagesMap);
+
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+
+        assertEquals(ksms.encodePublicKey(keyA), KeySetStrings.ctsKeySetPublicKeyA);
+        assertEquals(ksms.encodePublicKey(keyB), KeySetStrings.ctsKeySetPublicKeyB);
+        assertEquals(ksms.encodePublicKey(keyC), KeySetStrings.ctsKeySetPublicKeyC);
+    }
+
+    /*
+     * Add the keyset information for a package to a system w/no previous keysets
+     */
+    public void testAddSigningKSToPackageEmpty() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertEquals(1, ps.keySetData.getProperSigningKeySet());
+    }
+
+    /*
+     * upgrade an app (same packagename) with same keyset and verify that
+     * nothing changed.
+     */
+    public void testAddSigningKSToPackageUpgradeSame() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        /* add again, to represent upgrade of package */
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertEquals(1, ps.keySetData.getProperSigningKeySet());
+    }
+
+    /*
+     * upgrade an app (same packagename) with different unique keyset and verify
+     * that the old was removed.
+     */
+    public void testAddSigningKSToPackageUpgradeDiff() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        /* now upgrade with new key */
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        signingKeys.removeAt(0);
+        signingKeys.add(keyB);
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(2);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(2)));
+        assertEquals(2, ps.keySetData.getProperSigningKeySet());
+    }
+
+    /*
+     * upgrade an app (same packagename) with different keyset and verify
+     * that the old had its ref count reduced due to reference by other ps.
+     */
+    public void testAddSigningKSToPackageUpgradeDiff2() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps1 = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps1.name, ps1);
+        PackageSetting ps2 = generateFakePackageSetting("packageB");
+        mPackagesMap.put(ps2.name, ps2);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+        mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+        /* now upgrade with new key */
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        signingKeys.removeAt(0);
+        signingKeys.add(keyB);
+        mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(2, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        mapping = ksMapping.get(2);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(2)));
+        assertEquals(2, ps1.keySetData.getProperSigningKeySet());
+        assertEquals(1, ps2.keySetData.getProperSigningKeySet());
+    }
+
+    /*
+     * Add orthoganal keyset info to system and ensure previous keysets are
+     * unmodified.
+     */
+    public void testAddSigningKSToPackageNewOrtho() throws ReflectiveOperationException {
+
+        /* create PackageSettings and add to Settings mPackages */
+        PackageSetting ps1 = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps1.name, ps1);
+        PackageSetting ps2 = generateFakePackageSetting("packageB");
+        mPackagesMap.put(ps2.name, ps2);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys1 = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys1.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys1);
+
+        /* collect second signing key and add */
+        ArraySet<PublicKey> signingKeys2 = new ArraySet<PublicKey>();
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        signingKeys2.add(keyB);
+        mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys2);
+
+        /* verify first is unchanged */
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(2, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertEquals(1, ps1.keySetData.getProperSigningKeySet());
+
+        /* verify second */
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+        mapping = ksMapping.get(2);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new  Long(2)));
+        assertEquals(2, ps2.keySetData.getProperSigningKeySet());
+    }
+
+    /*
+     * Add identical keyset info to system via new package and ensure previous
+     * keysets has reference count incremented
+     */
+    public void testAddSigningKSToPackageNewSame() throws ReflectiveOperationException {
+
+        /* create PackageSettings and add to Settings mPackages */
+        PackageSetting ps1 = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps1.name, ps1);
+        PackageSetting ps2 = generateFakePackageSetting("packageB");
+        mPackagesMap.put(ps2.name, ps2);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+
+        /* add again for second package */
+        mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+        assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertEquals(1, ps1.keySetData.getProperSigningKeySet());
+        assertEquals(1, ps2.keySetData.getProperSigningKeySet());
+    }
+
+    /*
+     * add a package which is signed by a keyset which contains a previously seen
+     * public key and make sure its refernces are incremented.
+     */
+    public void testAddSigningKSToPackageSuper() throws ReflectiveOperationException {
+
+        /* create PackageSettings and add to Settings mPackages */
+        PackageSetting ps1 = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps1.name, ps1);
+        PackageSetting ps2 = generateFakePackageSetting("packageB");
+        mPackagesMap.put(ps2.name, ps2);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+
+        /* give ps2 a superset (add keyB) */
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        signingKeys.add(keyB);
+        mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(2, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(2, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        mapping = ksMapping.get(2);
+        assertEquals(2, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertTrue(mapping.contains(new Long(2)));
+        assertEquals(1, ps1.keySetData.getProperSigningKeySet());
+        assertEquals(2, ps2.keySetData.getProperSigningKeySet());
+    }
+
+    /*
+     * Upgrade an app (same pkgName) with different keyset which contains a public
+     * key from the previous keyset.  Verify old keyset removed and pub key ref
+     * count is accurate.
+     */
+    public void testAddSigningKSToPackageUpgradeDiffSuper() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        /* now with additional key */
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        signingKeys.add(keyB);
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3));
+
+        /* the pub key is removed w/prev keyset and may be either 2 or 3 */
+        assertTrue(keyA.equals(KeySetUtils.getPubKey(mKsms, 2)) || keyA.equals(KeySetUtils.getPubKey(mKsms, 3)));
+        assertTrue(keyB.equals(KeySetUtils.getPubKey(mKsms, 2)) || keyB.equals(KeySetUtils.getPubKey(mKsms, 3)));
+        assertFalse(KeySetUtils.getPubKey(mKsms, 2).equals(KeySetUtils.getPubKey(mKsms, 3)));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(2);
+        assertEquals(2, mapping.size());
+        assertTrue(mapping.contains(new Long(2)));
+        assertTrue(mapping.contains(new Long(3)));
+        assertEquals(2, ps.keySetData.getProperSigningKeySet());
+    }
+
+    /* add a defined keyset make sure it shows up */
+    public void testAddDefinedKSToPackageEmpty() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertNotNull(ps.keySetData.getAliases().get("aliasA"));
+        assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA"));
+    }
+
+    /* add 2 defined keysets which refer to same keyset and make sure ref-ct is 2 */
+    public void testAddDefinedKSToPackageDoubleAlias() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+        definedKS.put("aliasA", keys);
+        definedKS.put("aliasA2", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertNotNull(ps.keySetData.getAliases().get("aliasA"));
+        assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA"));
+        assertNotNull(ps.keySetData.getAliases().get("aliasA2"));
+        assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasA2"));
+    }
+
+    /* upgrd defined keyset ortho (make sure previous is removed for pkg) */
+    public void testAddDefinedKSToPackageOrthoUpgr() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        /* now upgrade to different defined key-set */
+        keys = new ArraySet<PublicKey>();
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        keys.add(keyB);
+        definedKS.remove("aliasA");
+        definedKS.put("aliasB", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(2);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(2)));
+        assertNull(ps.keySetData.getAliases().get("aliasA"));
+        assertNotNull(ps.keySetData.getAliases().get("aliasB"));
+        assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasB"));
+    }
+
+    /* upgrd defined keyset ortho but reuse alias (make sure old is removed and
+     * alias points to new keyset)
+     */
+    public void testAddDefinedKSToPackageOrthoUpgrAliasSame() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        /* now upgrade to different set w/same alias as before */
+        keys = new ArraySet<PublicKey>();
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        keys.add(keyB);
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(2);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(2)));
+        assertNotNull(ps.keySetData.getAliases().get("aliasA"));
+        assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasA"));
+    }
+
+     /* Start with defined ks of (A, B) and upgrade to (B, C).  Make sure B is
+      * unchanged. */
+    public void testAddDefinedKSToPackageOverlapUpgr() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect keys A and B and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys1 = new ArraySet<PublicKey>();
+        ArraySet<PublicKey> keys2 = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        keys1.add(keyA);
+        keys2.add(keyB);
+        definedKS.put("aliasA", keys1);
+        definedKS.put("aliasB", keys2);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        /* now upgrade to different set (B, C) */
+        keys1 = new ArraySet<PublicKey>();
+        PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+        keys1.add(keyC);
+        definedKS.remove("aliasA");
+        definedKS.put("aliasC", keys1);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 3));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3));
+        assertEquals(keyC, KeySetUtils.getPubKey(mKsms, 3));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(2, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(3);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(3)));
+        assertEquals(new Long(3), ps.keySetData.getAliases().get("aliasC"));
+
+        /* either keyset w/keyA or w/keyB was added first, address both cases */
+        if (1 == KeySetUtils.getKeySetRefCount(mKsms, 1)) {
+
+            /* keyB was added first and should have keyset 1 and pub-key 1 */
+            assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+            assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 2));
+            assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+            assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 1));
+            mapping = ksMapping.get(1);
+            assertEquals(1, mapping.size());
+            assertTrue(mapping.contains(new Long(1)));
+            assertEquals(new Long(1), ps.keySetData.getAliases().get("aliasB"));
+        } else {
+
+            /* keyA was added first and keyB has id 2 */
+            assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+            assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+            assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+            assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+            assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+            mapping = ksMapping.get(2);
+            assertEquals(1, mapping.size());
+            assertTrue(mapping.contains(new Long(2)));
+            assertEquals(new Long(2), ps.keySetData.getAliases().get("aliasB"));
+        }
+        assertNull(ps.keySetData.getAliases().get("aliasA"));
+    }
+
+    /* add defined keyset, remove it, add again and make sure diff id. */
+    public void testAddDefinedKSToPackageThree() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys1 = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys1.add(keyA);
+        definedKS.put("aliasA", keys1);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        /* now upgrade to different set */
+        ArraySet<PublicKey> keys2 = new ArraySet<PublicKey>();
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        keys2.add(keyB);
+        definedKS.remove("aliasA");
+        definedKS.put("aliasB", keys2);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        /* upgrade back to original */
+        definedKS.remove("aliasB");
+        definedKS.put("aliasA", keys1);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 2));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 3));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3));
+        assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 3));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        ArraySet<Long> mapping = ksMapping.get(3);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(3)));
+        assertEquals(new Long(3), ps.keySetData.getAliases().get("aliasA"));
+    }
+
+    /* add upgrade keyset for existing defined keyset and check that it is recorded */
+    public void testAddUpgradeKSToPackageEmpty() {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add, and denote as an upgrade keyset */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+        ArraySet<String> upgradeKS = new ArraySet<String>();
+        upgradeKS.add("aliasA");
+        mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+
+        assertEquals(1, ps.keySetData.getUpgradeKeySets().length);
+        assertEquals(1, ps.keySetData.getUpgradeKeySets()[0]);
+    }
+
+    /* add upgrade keyset for non-existing defined and check that it compains */
+    public void testAddUpgradeKSToPackageWrong() {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add and try to specify bogus upgrade keyset */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+        ArraySet<String> upgradeKS = new ArraySet<String>();
+        upgradeKS.add("aliasB");
+        try {
+            mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+        } catch (IllegalArgumentException e) {
+
+            /* should have been caught in packagemanager, so exception thrown */
+            return;
+        }
+        fail("Expected IllegalArgumentException when adding undefined upgrade keyset!!");
+    }
+
+    /* upgrade from defined keysets w/upgrade to different defined keysets and
+     * make sure the previously specified upgrade keyset has been removed. */
+    public void testAddUpgradeKSToPackageDisappear() {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+        ArraySet<String> upgradeKS = new ArraySet<String>();
+        upgradeKS.add("aliasA");
+        mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+
+        keys = new ArraySet<PublicKey>();
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        keys.add(keyB);
+        definedKS.remove("aliasA");
+        definedKS.put("aliasB", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+        assertNull(ps.keySetData.getUpgradeKeySets());
+    }
+
+    /* remove package and validate that keyset and public keys are removed */
+    public void testRemoveAppKSDataUnique() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect signing key and add */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
+
+        /* remove its references */
+        mKsms.removeAppKeySetDataLPw(ps.name);
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(0, ksMapping.size());
+        assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet());
+    }
+
+    /* remove package and validate that keysets remain if defined elsewhere but
+     * have refcounts decreased. */
+    public void testRemoveAppKSDataDup() throws ReflectiveOperationException {
+
+        /* create PackageSettings and add to Settings mPackages */
+        PackageSetting ps1 = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps1.name, ps1);
+        PackageSetting ps2 = generateFakePackageSetting("packageB");
+        mPackagesMap.put(ps2.name, ps2);
+
+        /* collect signing key and add for both packages */
+        ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        signingKeys.add(keyA);
+        mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
+        mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
+
+        /* remove references from first package */
+        mKsms.removeAppKeySetDataLPw(ps1.name);
+
+        assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(1, ksMapping.size());
+        assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps1.keySetData.getProperSigningKeySet());
+        assertEquals(1, ps2.keySetData.getProperSigningKeySet());
+    }
+
+    /* remove package which used defined and upgrade keysets and ensure  removed */
+    public void testRemoveAppKSDataDefined() throws ReflectiveOperationException {
+
+        /* create PackageSetting and add to Settings mPackages */
+        PackageSetting ps = generateFakePackageSetting("packageA");
+        mPackagesMap.put(ps.name, ps);
+
+        /* collect key and add */
+        ArrayMap<String, ArraySet<PublicKey>> definedKS = new ArrayMap<String, ArraySet<PublicKey>>();
+        ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        keys.add(keyA);
+
+        /* removal requires signing keyset to be specified (since all apps are
+         * assumed to have it).  We skipped this in the defined tests, but can't
+         * here. */
+        mKsms.addSigningKeySetToPackageLPw(ps.name, keys);
+
+        definedKS.put("aliasA", keys);
+        mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
+        ArraySet<String> upgradeKS = new ArraySet<String>();
+        upgradeKS.add("aliasA");
+        mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
+        mKsms.removeAppKeySetDataLPw(ps.name);
+
+        assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+        assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
+        assertEquals(0, ksMapping.size());
+        assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet());
+        assertEquals(0, ps.keySetData.getAliases().size());
+        assertNull(ps.keySetData.getUpgradeKeySets());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java b/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java
new file mode 100644
index 0000000..89d01ae
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetStrings.java
@@ -0,0 +1,137 @@
+/*
+ * 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.server.pm;
+
+public class KeySetStrings {
+
+    /*
+     * public keys taken from:
+     * openssl x509 -in cts-keyset-test-${N}.x509.pem -inform PEM -pubkey
+     * in /platform/cts/hostsidetests/appsecurity/certs/keysets
+     */
+    public static final String ctsKeySetPublicKeyA =
+            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwf5zJblvYSB7Ym7or/7Ggg"
+            + "AAu7mp7RrykPJsXhod8doFhVT5s7eF3A4MCE55vvANP7HvwMw2b+T6qx7Pq0VJtb"
+            + "bSDtlBHBtIc47Pjq0CsDg590BUcgKp7PdJ9J6UVgtzDnV6cGEpXmSag3sY+lqiW0"
+            + "4ytPhCVwzYTWGdYe9+TIl47cBrveRfLOlGrcuFQe+zCTmDFqzBKCRHK9b7l5PDWv"
+            + "XXyg65Uu/MBUA/TZWO0fEqOlxZG/nn6DUKQLhPdmJRXWJ3WqMNMhJGD+nKtkmdX7"
+            + "03xRqmg4h+6g0S7M9Y3IQ2NUGyw05AYzCguHB/Mv6uVIiW659wpbyb45TgKG3UhQ"
+            + "IDAQAB";
+
+    public static final String ctsKeySetPublicKeyB =
+            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoeFZqMqTbZiozFTXMkXtSK"
+            + "JRzn2qODZgvVXAAwKTi50xYcbPcHTfKxtif8+q7OCp/50JYDH32bg6wkUunn5+dE"
+            + "aHkxZY8d7uw46tQtl5dNGi+6cc4MezVLCS6nkqNDusAgdvgLU6Fl6SGi02KTp1vk"
+            + "t6CwLO977YJP7kt9ouDRTG7ASJiq3OyRRoOqYHhD9gpsbUq4w+1bXGfuuZujA1dX"
+            + "yovXtvrHUGOdFIEBYOVYGfCcwh3lXPmjNJMlHtKQkurq8/LH7a1B5ocoXCGsyR8Y"
+            + "HdlWfrqRAfzgOB1KCnNNmWqskU9LOci3uQn9IDeMEFmAd8FqF8SwV+4Ludk/xWGQ"
+            + "IDAQAB";
+
+    public static final String ctsKeySetPublicKeyC =
+            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwIJ/p9zZ6pGe7h1lBJULE"
+            + "5lbYbC3mh5G43OsJ+B0CebN4KzEKyVg+wmkuGSvG2xXUp1BlbipSjnTJ5bUt2iBu"
+            + "wB81Lvumg9GOfCpTBGtfE4a4igtfo7e2U8IbRzEYbhaZlBEmC1BDUvdTFdMRGZPu"
+            + "hUcMkwit4RpHkL6rttuOfaeoJwsgEjbELyzgcm+1Z49Den/JmmXNGMw1/QMibBFG"
+            + "vGkhu2rHg/SYiKpupclU4FIeALcOSnPkrrY6LuSATHDnYvuvK3Vhu0EBKID+rAv5"
+            + "j6BNvnu25SAf3GgS7PLuyVlhiE5p3hTevXn5g/7tjJlXa0FsbMlnFf53WyP9pRWw"
+            + "IDAQAB";
+
+    /*
+     * certs taken from packagemanager packages.xml output corresponding to certs in
+     * /platform/cts/hostsidetests/appsecurity/certs/keysets
+     */
+    public static final String ctsKeySetCertA =
+            "3082030b308201f3a0030201020209009d76e8a600170813300d06092a864886f7"
+            + "0d0101050500301c311a301806035504030c116374732d6b65797365742d7465"
+            + "73742d61301e170d3134303931313030343434385a170d343230313237303034"
+            + "3434385a301c311a301806035504030c116374732d6b65797365742d74657374"
+            + "2d6130820122300d06092a864886f70d01010105000382010f003082010a0282"
+            + "010100c1fe7325b96f61207b626ee8affec6820000bbb9a9ed1af290f26c5e1a"
+            + "1df1da058554f9b3b785dc0e0c084e79bef00d3fb1efc0cc366fe4faab1ecfab"
+            + "4549b5b6d20ed9411c1b48738ecf8ead02b03839f740547202a9ecf749f49e94"
+            + "560b730e757a7061295e649a837b18fa5aa25b4e32b4f842570cd84d619d61ef"
+            + "7e4c8978edc06bbde45f2ce946adcb8541efb309398316acc12824472bd6fb97"
+            + "93c35af5d7ca0eb952efcc05403f4d958ed1f12a3a5c591bf9e7e8350a40b84f"
+            + "7662515d62775aa30d3212460fe9cab6499d5fbd37c51aa683887eea0d12eccf"
+            + "58dc84363541b2c34e406330a0b8707f32feae548896eb9f70a5bc9be394e028"
+            + "6dd4850203010001a350304e301d0603551d0e04160414debf602e08b7573bce"
+            + "4816ac32eab215fb052892301f0603551d23041830168014debf602e08b7573b"
+            + "ce4816ac32eab215fb052892300c0603551d13040530030101ff300d06092a86"
+            + "4886f70d0101050500038201010092f1b8d08252d808d3051dce80780bd27eef"
+            + "e3f6b6d935398afb448209461b6f8b352e830d4358661e1b3e9eb9ab3937bddd"
+            + "581a28f533da1ebeb6838ce4a84ca64c43507c5ef9528917857e4d1c4c5996cf"
+            + "6b3d30823db514a715eeee709d69e38b4f0ef5dce4b08ce40fd52b39ac651311"
+            + "b6d1814913d922ce84748b6999256851fb583a49e35cecf79a527108df8e062d"
+            + "f4831addbb12a661999d41849e2545150cab74c91447dd15e55cdf3f8082dcab"
+            + "667c5cee3350d0f15d3970edcf3e81882e80985b0c0bf9917adb55c634de3a92"
+            + "e8fb5d9413b1703bec116b9ee9346b658f394acfe0c60406718be80b7110df8b"
+            + "44c984f001e1d16aac3831afee18";
+
+    public static final String ctsKeySetCertB =
+            "3082030b308201f3a003020102020900e670a5b2ec1e8a12300d06092a864886f7"
+            + "0d0101050500301c311a301806035504030c116374732d6b65797365742d7465"
+            + "73742d62301e170d3134303931313030343434315a170d343230313237303034"
+            + "3434315a301c311a301806035504030c116374732d6b65797365742d74657374"
+            + "2d6230820122300d06092a864886f70d01010105000382010f003082010a0282"
+            + "010100a1e159a8ca936d98a8cc54d73245ed48a251ce7daa383660bd55c00302"
+            + "938b9d3161c6cf7074df2b1b627fcfaaece0a9ff9d096031f7d9b83ac2452e9e"
+            + "7e7e744687931658f1deeec38ead42d97974d1a2fba71ce0c7b354b092ea792a"
+            + "343bac02076f80b53a165e921a2d36293a75be4b7a0b02cef7bed824fee4b7da"
+            + "2e0d14c6ec04898aadcec914683aa607843f60a6c6d4ab8c3ed5b5c67eeb99ba"
+            + "3035757ca8bd7b6fac750639d14810160e55819f09cc21de55cf9a33493251ed"
+            + "29092eaeaf3f2c7edad41e687285c21acc91f181dd9567eba9101fce0381d4a0"
+            + "a734d996aac914f4b39c8b7b909fd20378c10598077c16a17c4b057ee0bb9d93"
+            + "fc56190203010001a350304e301d0603551d0e04160414ccd4d9d47dcc18889d"
+            + "cba32de37e6570c88f8109301f0603551d23041830168014ccd4d9d47dcc1888"
+            + "9dcba32de37e6570c88f8109300c0603551d13040530030101ff300d06092a86"
+            + "4886f70d0101050500038201010061951cf9c9a629b30b560d53d62a72796edc"
+            + "97b0b210b567859311b14574abb052ef08cabb0b18cef5517597eabee9498a07"
+            + "a04472b8e6eee8668c05d2ff28141a36351593551f0c9d27feb4367fd0d23c76"
+            + "e36035f9d06d2d24b4167120fabdcfddfbe872bd127a602de8563ad6027ee19a"
+            + "fc21065cf02d6aaf97bf78388c3c129e72d1b31f5727896aaad7fe6773fbc285"
+            + "34e89194a75e1ecf64bcc5fa228e71e3be9efc78cb39bbabf60e334b403fc3e4"
+            + "9eb59c3407883d10efb04470a7d7d12114e7c9ddc3b381ffc43e8e8a830efa59"
+            + "38e47eef0d4dd39a80186c3b4236f812f52775941fe1dd73d51f6f50ab0916e3"
+            + "149c31feabcf38860be45d113a54";
+
+    public static final String ctsKeySetCertC =
+            "3082030b308201f3a0030201020209008f2e824e4e17810d300d06092a864886f7"
+            + "0d0101050500301c311a301806035504030c116374732d6b65797365742d7465"
+            + "73742d63301e170d3134303931313030343432325a170d343230313237303034"
+            + "3432325a301c311a301806035504030c116374732d6b65797365742d74657374"
+            + "2d6330820122300d06092a864886f70d01010105000382010f003082010a0282"
+            + "010100af0209fe9f7367aa467bb8759412542c4e656d86c2de68791b8dceb09f"
+            + "81d0279b3782b310ac9583ec2692e192bc6db15d4a750656e2a528e74c9e5b52"
+            + "dda206ec01f352efba683d18e7c2a53046b5f1386b88a0b5fa3b7b653c21b473"
+            + "1186e16999411260b504352f75315d3111993ee85470c9308ade11a4790beabb"
+            + "6db8e7da7a8270b201236c42f2ce0726fb5678f437a7fc99a65cd18cc35fd032"
+            + "26c1146bc6921bb6ac783f49888aa6ea5c954e0521e00b70e4a73e4aeb63a2ee"
+            + "4804c70e762fbaf2b7561bb41012880feac0bf98fa04dbe7bb6e5201fdc6812e"
+            + "cf2eec95961884e69de14debd79f983feed8c99576b416c6cc96715fe775b23f"
+            + "da515b0203010001a350304e301d0603551d0e041604141b8137c73974a17633"
+            + "686f93798a7f7b8385bded301f0603551d230418301680141b8137c73974a176"
+            + "33686f93798a7f7b8385bded300c0603551d13040530030101ff300d06092a86"
+            + "4886f70d01010505000382010100276ce2ca7b78b12aa2e432c8287075af91e5"
+            + "2a15a8586e23cdd7524a4c5ae04156307e95275cdfd841f2d28c0583cb36779e"
+            + "25d849a8b608eb48a84a50202a7825c7847e865409b1dd01303b5b1bdfafecab"
+            + "bfe1c6ec5f30ce1cb16b93db72ef726f77a48ca4f5ac5e12c4ad08c6df6fbf7e"
+            + "1548ef7ca80cf1d98abb550c0e28b246e8c0f1a975ffb624f1a4aeec11f01ba6"
+            + "02631d56645f5ae042dbf67b444b160711ca2629c456c5cc12e2ff56fa1332b6"
+            + "92483d14d2e6fb8e026246058fb5826e3958ee8f780d0fc2b840d51c2bbf0d24"
+            + "e9e108ef1c2d9ec13797bb4e5793349628a2ddb2a79c9d9c5736e7aea93e4552"
+            + "18fd162e0a42a4fbb4aa9df82b8a";
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java b/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java
new file mode 100644
index 0000000..9e1a366
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java
@@ -0,0 +1,89 @@
+/*
+ * 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.server.pm;
+
+import android.util.ArraySet;
+import android.util.LongSparseArray;
+
+import java.lang.reflect.Field;
+import java.security.PublicKey;
+
+public class KeySetUtils {
+
+    public static PublicKey getPubKey(KeySetManagerService ksms, long pkId)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field pkField = ksms.getClass().getDeclaredField("mPublicKeys");
+        pkField.setAccessible(true);
+        LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
+            (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(ksms);
+        KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
+        if (pkh == null) {
+            return null;
+        } else {
+            return pkh.getKey();
+        }
+    }
+
+    public static int getPubKeyRefCount(KeySetManagerService ksms, long pkId)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field pkField = ksms.getClass().getDeclaredField("mPublicKeys");
+        pkField.setAccessible(true);
+        LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
+            (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(ksms);
+        KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
+        if (pkh == null) {
+            return 0;
+        } else {
+            return pkh.getRefCountLPr();
+        }
+    }
+
+    public static int getKeySetRefCount(KeySetManagerService ksms, long keysetId)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field ksField = ksms.getClass().getDeclaredField("mKeySets");
+        ksField.setAccessible(true);
+        LongSparseArray<KeySetHandle> mKeySets =
+            (LongSparseArray<KeySetHandle>) ksField.get(ksms);
+        KeySetHandle ksh = mKeySets.get(keysetId);
+        if (ksh == null) {
+            return 0;
+        } else {
+            return ksh.getRefCountLPr();
+        }
+    }
+
+    public static LongSparseArray<ArraySet<Long>> getKeySetMapping(KeySetManagerService ksms)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field ksField = ksms.getClass().getDeclaredField("mKeySetMapping");
+        ksField.setAccessible(true);
+        return (LongSparseArray<ArraySet<Long>>) ksField.get(ksms);
+    }
+
+    public static Long getLastIssuedKeyId(KeySetManagerService ksms)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field ksField = ksms.getClass().getDeclaredField("lastIssuedKeyId");
+        ksField.setAccessible(true);
+        return (Long) ksField.get(ksms);
+    }
+
+    public static Long getLastIssuedKeySetId(KeySetManagerService ksms)
+            throws NoSuchFieldException, IllegalAccessException {
+        Field ksField = ksms.getClass().getDeclaredField("lastIssuedKeySetId");
+        ksField.setAccessible(true);
+        return (Long) ksField.get(ksms);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index a3f3a5d..ed1db6f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -21,15 +21,21 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
 
+import android.content.Context;
+import android.content.pm.PackageParser;
 import android.test.AndroidTestCase;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.LongSparseArray;
 
 import com.android.internal.os.AtomicFile;
 
+import java.lang.reflect.Constructor;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.security.PublicKey;
 
 public class PackageManagerSettingsTests extends AndroidTestCase {
     private static final String PACKAGE_NAME_2 = "com.google.app2";
@@ -67,18 +73,24 @@
                 + "</permissions>"
                 + "<package name=\"com.google.app1\" codePath=\"/system/app/app1.apk\" nativeLibraryPath=\"/data/data/com.google.app1/lib\" flags=\"1\" ft=\"1360e2caa70\" it=\"135f2f80d08\" ut=\"1360e2caa70\" version=\"1109\" sharedUserId=\"11000\">"
                 + "<sigs count=\"1\">"
-                + "<cert index=\"0\" key=\"308886\" />"
+                + "<cert index=\"0\" key=\"" + KeySetStrings.ctsKeySetCertA + "\" />"
                 + "</sigs>"
+                + "<proper-signing-keyset identifier=\"1\" />"
                 + "</package>"
                 + "<package name=\"com.google.app2\" codePath=\"/system/app/app2.apk\" nativeLibraryPath=\"/data/data/com.google.app2/lib\" flags=\"1\" ft=\"1360e578718\" it=\"135f2f80d08\" ut=\"1360e578718\" version=\"15\" enabled=\"3\" userId=\"11001\">"
                 + "<sigs count=\"1\">"
                 + "<cert index=\"0\" />"
                 + "</sigs>"
+                + "<proper-signing-keyset identifier=\"1\" />"
+                + "<defined-keyset alias=\"AB\" identifier=\"4\" />"
                 + "</package>"
                 + "<package name=\"com.android.app3\" codePath=\"/system/app/app3.apk\" nativeLibraryPath=\"/data/data/com.android.app3/lib\" flags=\"1\" ft=\"1360e577b60\" it=\"135f2f80d08\" ut=\"1360e577b60\" version=\"15\" userId=\"11030\">"
                 + "<sigs count=\"1\">"
-                + "<cert index=\"1\" key=\"308366\" />"
+                + "<cert index=\"1\" key=\"" + KeySetStrings.ctsKeySetCertB + "\" />"
                 + "</sigs>"
+                + "<proper-signing-keyset identifier=\"2\" />"
+                + "<upgrade-keyset identifier=\"3\" />"
+                + "<defined-keyset alias=\"C\" identifier=\"3\" />"
                 + "</package>"
                 + "<shared-user name=\"com.android.shared1\" userId=\"11000\">"
                 + "<sigs count=\"1\">"
@@ -88,6 +100,30 @@
                 + "<item name=\"android.permission.REBOOT\" />"
                 + "</perms>"
                 + "</shared-user>"
+                + "<keyset-settings version=\"1\">"
+                + "<keys>"
+                + "<public-key identifier=\"1\" value=\"" + KeySetStrings.ctsKeySetPublicKeyA + "\" />"
+                + "<public-key identifier=\"2\" value=\"" + KeySetStrings.ctsKeySetPublicKeyB + "\" />"
+                + "<public-key identifier=\"3\" value=\"" + KeySetStrings.ctsKeySetPublicKeyC + "\" />"
+                + "</keys>"
+                + "<keysets>"
+                + "<keyset identifier=\"1\">"
+                + "<key-id identifier=\"1\" />"
+                + "</keyset>"
+                + "<keyset identifier=\"2\">"
+                + "<key-id identifier=\"2\" />"
+                + "</keyset>"
+                + "<keyset identifier=\"3\">"
+                + "<key-id identifier=\"3\" />"
+                + "</keyset>"
+                + "<keyset identifier=\"4\">"
+                + "<key-id identifier=\"1\" />"
+                + "<key-id identifier=\"2\" />"
+                + "</keyset>"
+                + "</keysets>"
+                + "<lastIssuedKeyId value=\"3\" />"
+                + "<lastIssuedKeySetId value=\"4\" />"
+                + "</keyset-settings>"
                 + "</packages>").getBytes());
     }
 
@@ -131,6 +167,104 @@
         writePackagesList();
     }
 
+    private void createUserManagerServiceRef() throws ReflectiveOperationException {
+        Constructor<UserManagerService> umsc =
+                UserManagerService.class.getDeclaredConstructor(
+                        Context.class,
+                        PackageManagerService.class,
+                        Object.class,
+                        Object.class,
+                        File.class,
+                        File.class);
+        umsc.setAccessible(true);
+        UserManagerService ums = umsc.newInstance(getContext(), null,
+                new Object(), new Object(), getContext().getFilesDir(),
+                new File(getContext().getFilesDir(), "user"));
+    }
+
+    private void verifyKeySetMetaData(Settings settings)
+            throws ReflectiveOperationException, IllegalAccessException {
+        ArrayMap<String, PackageSetting> packages = settings.mPackages;
+        KeySetManagerService ksms = settings.mKeySetManagerService;
+
+        /* verify keyset and public key ref counts */
+        assertEquals(2, KeySetUtils.getKeySetRefCount(ksms, 1));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(ksms, 2));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(ksms, 3));
+        assertEquals(1, KeySetUtils.getKeySetRefCount(ksms, 4));
+        assertEquals(2, KeySetUtils.getPubKeyRefCount(ksms, 1));
+        assertEquals(2, KeySetUtils.getPubKeyRefCount(ksms, 2));
+        assertEquals(1, KeySetUtils.getPubKeyRefCount(ksms, 3));
+
+        /* verify public keys properly read */
+        PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+        PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+        PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+        assertEquals(keyA, KeySetUtils.getPubKey(ksms, 1));
+        assertEquals(keyB, KeySetUtils.getPubKey(ksms, 2));
+        assertEquals(keyC, KeySetUtils.getPubKey(ksms, 3));
+
+        /* verify mapping is correct (ks -> pub keys) */
+        LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(ksms);
+        ArraySet<Long> mapping = ksMapping.get(1);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        mapping = ksMapping.get(2);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(2)));
+        mapping = ksMapping.get(3);
+        assertEquals(1, mapping.size());
+        assertTrue(mapping.contains(new Long(3)));
+        mapping = ksMapping.get(4);
+        assertEquals(2, mapping.size());
+        assertTrue(mapping.contains(new Long(1)));
+        assertTrue(mapping.contains(new Long(2)));
+
+        /* verify lastIssuedIds are consistent */
+        assertEquals(new Long(3), KeySetUtils.getLastIssuedKeyId(ksms));
+        assertEquals(new Long(4), KeySetUtils.getLastIssuedKeySetId(ksms));
+
+        /* verify packages have been given the appropriat information */
+        PackageSetting ps = packages.get("com.google.app1");
+        assertEquals(1, ps.keySetData.getProperSigningKeySet());
+        ps = packages.get("com.google.app2");
+        assertEquals(1, ps.keySetData.getProperSigningKeySet());
+        assertEquals(new Long(4), ps.keySetData.getAliases().get("AB"));
+        ps = packages.get("com.android.app3");
+        assertEquals(2, ps.keySetData.getProperSigningKeySet());
+        assertEquals(new Long(3), ps.keySetData.getAliases().get("C"));
+        assertEquals(1, ps.keySetData.getUpgradeKeySets().length);
+        assertEquals(3, ps.keySetData.getUpgradeKeySets()[0]);
+    }
+
+    /* make sure our initialized keysetmanagerservice metadata matches packages.xml */
+    public void testReadKeySetSettings()
+            throws ReflectiveOperationException, IllegalAccessException {
+
+        /* write out files and read */
+        writeOldFiles();
+        createUserManagerServiceRef();
+        Settings settings = new Settings(getContext().getFilesDir(), new Object());
+        assertEquals(true, settings.readLPw(null, null, 0, false));
+        verifyKeySetMetaData(settings);
+    }
+
+    /* read in data, write it out, and read it back in.  Verify same. */
+    public void testWriteKeySetSettings()
+            throws ReflectiveOperationException, IllegalAccessException {
+
+        /* write out files and read */
+        writeOldFiles();
+        createUserManagerServiceRef();
+        Settings settings = new Settings(getContext().getFilesDir(), new Object());
+        assertEquals(true, settings.readLPw(null, null, 0, false));
+
+        /* write out, read back in and verify the same */
+        settings.writeLPr();
+        assertEquals(true, settings.readLPw(null, null, 0, false));
+        verifyKeySetMetaData(settings);
+    }
+
     public void testSettingsReadOld() {
         // Write the package files and make sure they're parsed properly the first time
         writeOldFiles();
@@ -149,9 +283,11 @@
         assertEquals(COMPONENT_ENABLED_STATE_DEFAULT, ps.getEnabled(1));
     }
 
-    public void testNewPackageRestrictionsFile() {
+    public void testNewPackageRestrictionsFile() throws ReflectiveOperationException {
+
         // Write the package files and make sure they're parsed properly the first time
         writeOldFiles();
+        createUserManagerServiceRef();
         Settings settings = new Settings(getContext().getFilesDir(), new Object());
         assertEquals(true, settings.readLPw(null, null, 0, false));
         settings.writeLPr();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 7dce83e..81c5e6a 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -28,6 +28,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
@@ -79,6 +81,7 @@
         mResolver = context.getContentResolver();
         mDbHelper = new DatabaseHelper(context);
         mSoundTriggerHelper = new SoundTriggerHelper(context);
+        mServiceStub = new VoiceInteractionManagerServiceStub();
     }
 
     @Override
@@ -104,8 +107,7 @@
     }
 
     // implementation entry point and binder service
-    private final VoiceInteractionManagerServiceStub mServiceStub
-            = new VoiceInteractionManagerServiceStub();
+    private final VoiceInteractionManagerServiceStub mServiceStub;
 
     class VoiceInteractionManagerServiceStub extends IVoiceInteractionManagerService.Stub {
 
@@ -113,6 +115,11 @@
 
         private boolean mSafeMode;
         private int mCurUser;
+        private final boolean mEnableService;
+
+        VoiceInteractionManagerServiceStub() {
+            mEnableService = shouldEnableService(mContext.getResources());
+        }
 
         @Override
         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
@@ -138,8 +145,7 @@
             VoiceInteractionServiceInfo curInteractorInfo = null;
             if (DEBUG) Slog.d(TAG, "curInteractorStr=" + curInteractorStr
                     + " curRecognizer=" + curRecognizer);
-            if (curInteractorStr == null && curRecognizer != null
-                    && !ActivityManager.isLowRamDeviceStatic()) {
+            if (curInteractorStr == null && curRecognizer != null && mEnableService) {
                 // If there is no interactor setting, that means we are upgrading
                 // from an older platform version.  If the current recognizer is not
                 // set or matches the preferred recognizer, then we want to upgrade
@@ -159,7 +165,7 @@
 
             // If we are on a svelte device, make sure an interactor is not currently
             // enabled; if it is, turn it off.
-            if (ActivityManager.isLowRamDeviceStatic() && curInteractorStr != null) {
+            if (!mEnableService && curInteractorStr != null) {
                 if (!TextUtils.isEmpty(curInteractorStr)) {
                     if (DEBUG) Slog.d(TAG, "Svelte device; disabling interactor");
                     setCurInteractor(null, userHandle);
@@ -192,7 +198,7 @@
             }
 
             // Initializing settings, look for an interactor first (but only on non-svelte).
-            if (curInteractorInfo == null && !ActivityManager.isLowRamDeviceStatic()) {
+            if (curInteractorInfo == null && mEnableService) {
                 curInteractorInfo = findAvailInteractor(userHandle, null);
             }
 
@@ -218,6 +224,12 @@
             }
         }
 
+        private boolean shouldEnableService(Resources res) {
+            // VoiceInteractionService should not be enabled on low ram devices unless it has the config flag.
+            return !ActivityManager.isLowRamDeviceStatic()
+                    || res.getBoolean(com.android.internal.R.bool.config_forceEnableVoiceInteractionService);
+        }
+
         public void systemRunning(boolean safeMode) {
             mSafeMode = safeMode;
 
@@ -740,6 +752,7 @@
             }
             synchronized (this) {
                 pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n");
+                pw.println("  mEnableService: " + mEnableService);
                 if (mImpl == null) {
                     pw.println("  (No active implementation)");
                     return;
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index bf8fac6..b5d566a 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -14,7 +14,6 @@
 
 package android.telecom;
 
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -41,7 +40,7 @@
      *
      * @hide
      * */
-    public static void setDefaultPhoneApplication(Context context, String packageName) {
+    public static void setDefaultDialerApplication(Context context, String packageName) {
         // Get old package name
         String oldPackageName = Settings.Secure.getString(context.getContentResolver(),
                 Settings.Secure.DIALER_DEFAULT_APPLICATION);
@@ -52,13 +51,12 @@
         }
 
         // Only make the change if the new package belongs to a valid phone application
-        List<ComponentName> componentNames = getInstalledDialerApplications(context);
-        final ComponentName foundComponent = getComponentName(componentNames, packageName);
+        List<String> packageNames = getInstalledDialerApplications(context);
 
-        if (foundComponent != null) {
+        if (packageNames.contains(packageName)) {
             // Update the secure setting.
             Settings.Secure.putString(context.getContentResolver(),
-                    Settings.Secure.DIALER_DEFAULT_APPLICATION, foundComponent.getPackageName());
+                    Settings.Secure.DIALER_DEFAULT_APPLICATION, packageName);
         }
     }
 
@@ -73,29 +71,31 @@
      *
      * @hide
      * */
-    public static ComponentName getDefaultDialerApplication(Context context) {
+    public static String getDefaultDialerApplication(Context context) {
         String defaultPackageName = Settings.Secure.getString(context.getContentResolver(),
                 Settings.Secure.DIALER_DEFAULT_APPLICATION);
 
-        final List<ComponentName> componentNames = getInstalledDialerApplications(context);
-        if (!TextUtils.isEmpty(defaultPackageName)) {
-            final ComponentName defaultDialer =
-                    getComponentName(componentNames, defaultPackageName);
-            if (defaultDialer != null) {
-                return defaultDialer;
-            }
+
+        final List<String> packageNames = getInstalledDialerApplications(context);
+
+        // Verify that the default dialer has not been disabled or uninstalled.
+        if (packageNames.contains(defaultPackageName)) {
+            return defaultPackageName;
         }
 
         // No user-set dialer found, fallback to system dialer
-        String systemDialer = getTelecomManager(context).getSystemDialerPackage();
+        String systemDialerPackageName = getTelecomManager(context).getSystemDialerPackage();
 
-        if (TextUtils.isEmpty(systemDialer)) {
+        if (TextUtils.isEmpty(systemDialerPackageName)) {
             // No system dialer configured at build time
             return null;
         }
 
-        // Verify that the system dialer has not been disabled.
-        return getComponentName(componentNames, systemDialer);
+        if (packageNames.contains(systemDialerPackageName)) {
+            return systemDialerPackageName;
+        } else {
+            return null;
+        }
     }
 
     /**
@@ -109,63 +109,46 @@
      *
      * @hide
      **/
-    public static List<ComponentName> getInstalledDialerApplications(Context context) {
+    public static List<String> getInstalledDialerApplications(Context context) {
         PackageManager packageManager = context.getPackageManager();
 
         // Get the list of apps registered for the DIAL intent with empty scheme
         Intent intent = new Intent(Intent.ACTION_DIAL);
         List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
 
-        List<ComponentName> componentNames = new ArrayList<ComponentName> ();
+        List<String> packageNames = new ArrayList<>();
 
         for (ResolveInfo resolveInfo : resolveInfoList) {
             final ActivityInfo activityInfo = resolveInfo.activityInfo;
             if (activityInfo == null) {
                 continue;
             }
-            final ComponentName componentName =
-                    new ComponentName(activityInfo.packageName, activityInfo.name);
-            componentNames.add(componentName);
+            packageNames.add(activityInfo.packageName);
         }
 
         // TODO: Filter for apps that don't handle DIAL intent with tel scheme
-        return componentNames;
+        return packageNames;
     }
 
     /**
-     * Returns the {@link ComponentName} for the installed dialer application for a given package
-     * name.
+     * Determines if the package name belongs to the user-selected default dialer or the preloaded
+     * system dialer, and thus should be allowed to perform certain privileged operations.
      *
      * @param context A valid context.
-     * @param packageName to retrieve the {@link ComponentName} for.
+     * @param packageName of the package to check for.
      *
-     * @return The {@link ComponentName} for the installed dialer application corresponding to the
-     * package name, or null if none is found.
+     * @return {@code true} if the provided package name corresponds to the user-selected default
+     *         dialer or the preloaded system dialer, {@code false} otherwise.
      *
      * @hide
      */
-    public static ComponentName getDialerApplicationForPackageName(Context context,
-            String packageName) {
-        return getComponentName(getInstalledDialerApplications(context), packageName);
-    }
-
-    /**
-     * Returns the component from a list of application components that corresponds to the package
-     * name.
-     *
-     * @param componentNames A list of component names
-     * @param packageName The package name to look for
-     * @return The {@link ComponentName} that matches the provided packageName, or null if not
-     *         found.
-     */
-    private static ComponentName getComponentName(List<ComponentName> componentNames,
-            String packageName) {
-        for (ComponentName componentName : componentNames) {
-            if (TextUtils.equals(packageName, componentName.getPackageName())) {
-                return componentName;
-            }
+    public static boolean isDefaultOrSystemDialer(Context context, String packageName) {
+        if (TextUtils.isEmpty(packageName)) {
+            return false;
         }
-        return null;
+        final TelecomManager tm = getTelecomManager(context);
+        return packageName.equals(tm.getDefaultDialerPackage())
+                || packageName.equals(tm.getSystemDialerPackage());
     }
 
     private static TelecomManager getTelecomManager(Context context) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 4d2d100..e1091f0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -220,7 +220,8 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_restore(long nativeCanvas) {
+    /*package*/ static void native_restore(long nativeCanvas, boolean throwOnUnderflow) {
+        // FIXME: implement throwOnUnderflow.
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
         if (canvasDelegate == null) {
@@ -231,7 +232,9 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_restoreToCount(long nativeCanvas, int saveCount) {
+    /*package*/ static void native_restoreToCount(long nativeCanvas, int saveCount,
+            boolean throwOnUnderflow) {
+        // FIXME: implement throwOnUnderflow.
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
         if (canvasDelegate == null) {
@@ -844,7 +847,7 @@
     @LayoutlibDelegate
     /*package*/ static void native_drawText(long nativeCanvas, char[] text, int index, int count,
             float startX, float startY, int flags, long paint, long typeface) {
-        drawText(nativeCanvas, text, index, count, startX, startY, flags == Canvas.DIRECTION_RTL,
+        drawText(nativeCanvas, text, index, count, startX, startY, (flags & 1) != 0,
                 paint, typeface);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 8ffd1d8..f5ef01b 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -1137,7 +1137,7 @@
     }
 
     private void reset() {
-        mFlags = Paint.DEFAULT_PAINT_FLAGS;
+        mFlags = Paint.DEFAULT_PAINT_FLAGS | Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
         mColor = 0xFF000000;
         mStyle = Paint.Style.FILL.nativeInt;
         mCap = Paint.Cap.BUTT.nativeInt;
diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
index e72a0db..51d32e3 100644
--- a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
@@ -46,16 +46,12 @@
     /*package*/ static boolean drawChild(ViewGroup thisVG, Canvas canvas, View child,
             long drawingTime) {
         if (child.getZ() > thisVG.getZ()) {
+            // The background's bounds are set lazily. Make sure they are set correctly so that
+            // the outline obtained is correct.
+            child.setBackgroundBounds();
             ViewOutlineProvider outlineProvider = child.getOutlineProvider();
-            Outline outline = new Outline();
+            Outline outline = child.mAttachInfo.mTmpOutline;
             outlineProvider.getOutline(child, outline);
-            if (outline.mPath == null && outline.mRect == null) {
-                // Sometimes, the bounds of the background drawable are not set until View.draw()
-                // is called. So, we set the bounds manually and try to get the outline again.
-                child.getBackground().setBounds(0, 0, child.mRight - child.mLeft,
-                        child.mBottom - child.mTop);
-                outlineProvider.getOutline(child, outline);
-            }
             if (outline.mPath != null || (outline.mRect != null && !outline.mRect.isEmpty())) {
                 int restoreTo = transformCanvas(thisVG, canvas, child);
                 drawShadow(thisVG, canvas, child, outline);